diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2008-05-05 04:00:00 +0400 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:15:55 +0300 |
commit | 3901bf0ab88106a5b031cba7bc18d60cdebf7eef (patch) | |
tree | 808a2489abed822223b118b64e0553db80af6087 /C | |
parent | bd1fa36322ac27f5715433b388742893d6524516 (diff) |
4.58 beta
Diffstat (limited to 'C')
-rwxr-xr-x | C/7zBuf.c | 36 | ||||
-rwxr-xr-x | C/7zBuf.h | 21 | ||||
-rwxr-xr-x | C/7zCrc.c | 5 | ||||
-rwxr-xr-x | C/7zCrc.h | 5 | ||||
-rwxr-xr-x | C/7zCrcT8.c | 5 | ||||
-rwxr-xr-x | C/Aes.c (renamed from C/Crypto/Aes.c) | 93 | ||||
-rwxr-xr-x | C/Aes.h | 48 | ||||
-rwxr-xr-x | C/Alloc.c | 5 | ||||
-rwxr-xr-x | C/Alloc.h | 5 | ||||
-rwxr-xr-x | C/Archive/7z/7z.dsp (renamed from C/Archive/7z/7z_C.dsp) | 72 | ||||
-rwxr-xr-x | C/Archive/7z/7z.dsw (renamed from C/Archive/7z/7z_C.dsw) | 2 | ||||
-rwxr-xr-x | C/Archive/7z/7zAlloc.c | 19 | ||||
-rwxr-xr-x | C/Archive/7z/7zAlloc.h | 19 | ||||
-rwxr-xr-x | C/Archive/7z/7zBuffer.c | 29 | ||||
-rwxr-xr-x | C/Archive/7z/7zBuffer.h | 19 | ||||
-rwxr-xr-x | C/Archive/7z/7zDecode.c | 280 | ||||
-rwxr-xr-x | C/Archive/7z/7zDecode.h | 16 | ||||
-rwxr-xr-x | C/Archive/7z/7zExtract.c | 77 | ||||
-rwxr-xr-x | C/Archive/7z/7zExtract.h | 10 | ||||
-rwxr-xr-x | C/Archive/7z/7zHeader.c | 6 | ||||
-rwxr-xr-x | C/Archive/7z/7zHeader.h | 5 | ||||
-rwxr-xr-x | C/Archive/7z/7zIn.c | 547 | ||||
-rwxr-xr-x | C/Archive/7z/7zIn.h | 70 | ||||
-rwxr-xr-x | C/Archive/7z/7zItem.c | 154 | ||||
-rwxr-xr-x | C/Archive/7z/7zItem.h | 86 | ||||
-rwxr-xr-x | C/Archive/7z/7zMain.c | 112 | ||||
-rwxr-xr-x | C/Archive/7z/7zMethodID.c | 10 | ||||
-rwxr-xr-x | C/Archive/7z/7zMethodID.h | 10 | ||||
-rwxr-xr-x | C/Archive/7z/makefile | 60 | ||||
-rwxr-xr-x | C/Archive/7z/makefile.gcc | 23 | ||||
-rwxr-xr-x | C/Bcj2.c (renamed from C/Compress/Branch/BranchX86_2.c) | 57 | ||||
-rwxr-xr-x | C/Bcj2.h (renamed from C/Compress/Branch/BranchX86_2.h) | 20 | ||||
-rwxr-xr-x | C/Bra.c | 135 | ||||
-rwxr-xr-x | C/Bra.h | 62 | ||||
-rwxr-xr-x | C/Bra86.c (renamed from C/Compress/Branch/BranchX86.c) | 27 | ||||
-rwxr-xr-x | C/BraIA64.c (renamed from C/Compress/Branch/BranchIA64.c) | 29 | ||||
-rwxr-xr-x | C/BwtSort.c | 516 | ||||
-rwxr-xr-x | C/BwtSort.h | 24 | ||||
-rwxr-xr-x | C/Compress/Branch/BranchARM.c | 26 | ||||
-rwxr-xr-x | C/Compress/Branch/BranchARM.h | 10 | ||||
-rwxr-xr-x | C/Compress/Branch/BranchARMThumb.c | 35 | ||||
-rwxr-xr-x | C/Compress/Branch/BranchARMThumb.h | 10 | ||||
-rwxr-xr-x | C/Compress/Branch/BranchIA64.h | 10 | ||||
-rwxr-xr-x | C/Compress/Branch/BranchPPC.c | 36 | ||||
-rwxr-xr-x | C/Compress/Branch/BranchPPC.h | 10 | ||||
-rwxr-xr-x | C/Compress/Branch/BranchSPARC.c | 36 | ||||
-rwxr-xr-x | C/Compress/Branch/BranchSPARC.h | 10 | ||||
-rwxr-xr-x | C/Compress/Branch/BranchTypes.h | 51 | ||||
-rwxr-xr-x | C/Compress/Branch/BranchX86.h | 12 | ||||
-rwxr-xr-x | C/Compress/Lzma/LzmaDecode.c | 584 | ||||
-rwxr-xr-x | C/Compress/Lzma/LzmaDecode.h | 113 | ||||
-rwxr-xr-x | C/Compress/Lzma/LzmaDecodeSize.c | 712 | ||||
-rwxr-xr-x | C/Compress/Lzma/LzmaStateDecode.c | 521 | ||||
-rwxr-xr-x | C/Compress/Lzma/LzmaStateDecode.h | 96 | ||||
-rwxr-xr-x | C/Compress/Lzma/LzmaStateTest.c | 195 | ||||
-rwxr-xr-x | C/Compress/Lzma/LzmaTest.c | 342 | ||||
-rwxr-xr-x | C/Compress/Lzma/LzmaTypes.h | 45 | ||||
-rwxr-xr-x | C/CpuArch.h | 32 | ||||
-rwxr-xr-x | C/Crypto/Aes.h | 40 | ||||
-rwxr-xr-x | C/HuffEnc.c (renamed from C/Compress/Huffman/HuffmanEncode.c) | 12 | ||||
-rwxr-xr-x | C/HuffEnc.h (renamed from C/Compress/Huffman/HuffmanEncode.h) | 11 | ||||
-rwxr-xr-x | C/IStream.h | 19 | ||||
-rwxr-xr-x | C/LzFind.c (renamed from C/Compress/Lz/MatchFinder.c) | 85 | ||||
-rwxr-xr-x | C/LzFind.h (renamed from C/Compress/Lz/MatchFinder.h) | 22 | ||||
-rwxr-xr-x | C/LzFindMt.c (renamed from C/Compress/Lz/MatchFinderMt.c) | 95 | ||||
-rwxr-xr-x | C/LzFindMt.h (renamed from C/Compress/Lz/MatchFinderMt.h) | 18 | ||||
-rwxr-xr-x | C/LzHash.h (renamed from C/Compress/Lz/LzHash.h) | 33 | ||||
-rwxr-xr-x | C/LzmaDec.c | 1014 | ||||
-rwxr-xr-x | C/LzmaDec.h | 232 | ||||
-rwxr-xr-x | C/LzmaEnc.c | 2332 | ||||
-rwxr-xr-x | C/LzmaEnc.h | 74 | ||||
-rwxr-xr-x | C/LzmaLib.c | 46 | ||||
-rwxr-xr-x | C/LzmaLib.h | 135 | ||||
-rwxr-xr-x | C/LzmaLib/LzmaLib.def | 4 | ||||
-rwxr-xr-x | C/LzmaLib/LzmaLib.dsp | 178 | ||||
-rwxr-xr-x | C/LzmaLib/LzmaLib.dsw | 29 | ||||
-rwxr-xr-x | C/LzmaLib/LzmaLibExports.c | 14 | ||||
-rwxr-xr-x | C/LzmaLib/makefile | 37 | ||||
-rwxr-xr-x | C/LzmaLib/resource.rc | 4 | ||||
-rwxr-xr-x | C/LzmaUtil/Lzma86Dec.c | 61 | ||||
-rwxr-xr-x | C/LzmaUtil/Lzma86Dec.h | 45 | ||||
-rwxr-xr-x | C/LzmaUtil/Lzma86Enc.c | 113 | ||||
-rwxr-xr-x | C/LzmaUtil/Lzma86Enc.h | 72 | ||||
-rwxr-xr-x | C/LzmaUtil/LzmaUtil.c | 311 | ||||
-rwxr-xr-x | C/LzmaUtil/LzmaUtil.dsp | 152 | ||||
-rwxr-xr-x | C/LzmaUtil/LzmaUtil.dsw | 29 | ||||
-rwxr-xr-x | C/LzmaUtil/makefile | 27 | ||||
-rwxr-xr-x | C/LzmaUtil/makefile.gcc | 36 | ||||
-rwxr-xr-x | C/RotateDefs.h | 22 | ||||
-rwxr-xr-x | C/Sha256.c | 206 | ||||
-rwxr-xr-x | C/Sha256.h | 24 | ||||
-rwxr-xr-x | C/Sort.c | 5 | ||||
-rwxr-xr-x | C/Sort.h | 9 | ||||
-rwxr-xr-x | C/Threads.c | 71 | ||||
-rwxr-xr-x | C/Threads.h | 43 | ||||
-rwxr-xr-x | C/Types.h | 152 |
96 files changed, 7252 insertions, 4165 deletions
diff --git a/C/7zBuf.c b/C/7zBuf.c new file mode 100755 index 00000000..14e7f4e2 --- /dev/null +++ b/C/7zBuf.c @@ -0,0 +1,36 @@ +/* 7zBuf.c -- Byte Buffer +2008-03-28 +Igor Pavlov +Public domain */ + +#include "7zBuf.h" + +void Buf_Init(CBuf *p) +{ + p->data = 0; + p->size = 0; +} + +int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc) +{ + p->size = 0; + if (size == 0) + { + p->data = 0; + return 1; + } + p->data = (Byte *)alloc->Alloc(alloc, size); + if (p->data != 0) + { + p->size = size; + return 1; + } + return 0; +} + +void Buf_Free(CBuf *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->data); + p->data = 0; + p->size = 0; +} diff --git a/C/7zBuf.h b/C/7zBuf.h new file mode 100755 index 00000000..d827aa86 --- /dev/null +++ b/C/7zBuf.h @@ -0,0 +1,21 @@ +/* 7zBuf.h -- Byte Buffer +2008-05-01 +Igor Pavlov +Public domain */ + +#ifndef __7Z_BUF_H +#define __7Z_BUF_H + +#include "Types.h" + +typedef struct +{ + Byte *data; + size_t size; +} CBuf; + +void Buf_Init(CBuf *p); +int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc); +void Buf_Free(CBuf *p, ISzAlloc *alloc); + +#endif @@ -1,4 +1,7 @@ -/* 7zCrc.c */ +/* 7zCrc.c -- CRC32 calculation +2008-03-13 +Igor Pavlov +Public domain */ #include "7zCrc.h" @@ -1,4 +1,7 @@ -/* 7zCrc.h */ +/* 7zCrc.h -- CRC32 calculation +2008-03-13 +Igor Pavlov +Public domain */ #ifndef __7Z_CRC_H #define __7Z_CRC_H diff --git a/C/7zCrcT8.c b/C/7zCrcT8.c index 83aa95f7..cd80e262 100755 --- a/C/7zCrcT8.c +++ b/C/7zCrcT8.c @@ -1,4 +1,7 @@ -/* 7zCrcT8.c */ +/* 7zCrcT8.c -- CRC32 calculation with 8 tables +2008-03-19 +Igor Pavlov +Public domain */ #include "7zCrc.h" diff --git a/C/Crypto/Aes.c b/C/Aes.c index 205edbc8..6e2b7bf0 100755 --- a/C/Crypto/Aes.c +++ b/C/Aes.c @@ -1,10 +1,13 @@ -/* Aes.h */ +/* Aes.c -- AES encryption / decryption +2008-03-26 +Igor Pavlov +Public domain */ #include "Aes.h" -#include "../CpuArch.h" +#include "CpuArch.h" -UInt32 T[256 * 4]; -Byte Sbox[256] = { +static UInt32 T[256 * 4]; +static Byte Sbox[256] = { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, @@ -22,10 +25,10 @@ Byte Sbox[256] = { 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}; -UInt32 D[256 * 4]; -Byte InvS[256]; +static UInt32 D[256 * 4]; +static Byte InvS[256]; -Byte Rcon[11] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 }; +static Byte Rcon[11] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 }; #define xtime(x) ((((x) << 1) ^ (((x) & 0x80) != 0 ? 0x1B : 0)) & 0xFF) @@ -36,7 +39,7 @@ Byte Rcon[11] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x #define gb2(x) (((x) >> (16)) & 0xFF) #define gb3(x) (((x) >> (24)) & 0xFF) -void MY_FAST_CALL AesGenTables(void) +void AesGenTables(void) { unsigned i; for (i = 0; i < 256; i++) @@ -101,7 +104,7 @@ void MY_FAST_CALL AesGenTables(void) #define FD(i, x) InvS[gb ## x(m[(i - x) & 3])] #define FD4(i) dest[i] = Ui32(FD(i, 0), FD(i, 1), FD(i, 2), FD(i, 3)) ^ w[i]; -void MY_FAST_CALL AesSetKeyEncode(CAes *p, const Byte *key, unsigned keySize) +void Aes_SetKeyEncode(CAes *p, const Byte *key, unsigned keySize) { unsigned i, wSize; UInt32 *w; @@ -126,11 +129,11 @@ void MY_FAST_CALL AesSetKeyEncode(CAes *p, const Byte *key, unsigned keySize) } } -void MY_FAST_CALL AesSetKeyDecode(CAes *p, const Byte *key, unsigned keySize) +void Aes_SetKeyDecode(CAes *p, const Byte *key, unsigned keySize) { unsigned i, num; UInt32 *w; - AesSetKeyEncode(p, key, keySize); + Aes_SetKeyEncode(p, key, keySize); num = p->numRounds2 * 8 - 4; w = p->rkey + 4; for (i = 0; i < num; i++) @@ -144,7 +147,7 @@ void MY_FAST_CALL AesSetKeyDecode(CAes *p, const Byte *key, unsigned keySize) } } -void MY_FAST_CALL AesEncode32(const UInt32 *src, UInt32 *dest, const UInt32 *w, unsigned numRounds2) +static void AesEncode32(UInt32 *dest, const UInt32 *src, const UInt32 *w, unsigned numRounds2) { UInt32 s[4]; UInt32 m[4]; @@ -165,7 +168,7 @@ void MY_FAST_CALL AesEncode32(const UInt32 *src, UInt32 *dest, const UInt32 *w, FT4(0); FT4(1); FT4(2); FT4(3); } -void MY_FAST_CALL AesDecode32(const UInt32 *src, UInt32 *dest, const UInt32 *w, unsigned numRounds2) +static void AesDecode32(UInt32 *dest, const UInt32 *src, const UInt32 *w, unsigned numRounds2) { UInt32 s[4]; UInt32 m[4]; @@ -185,26 +188,26 @@ void MY_FAST_CALL AesDecode32(const UInt32 *src, UInt32 *dest, const UInt32 *w, FD4(0); FD4(1); FD4(2); FD4(3); } -#ifdef LITTLE_ENDIAN_UNALIGN -#define GetUi32(p) (*(const UInt32 *)(p)) -#define SetUi32(p, d) *(UInt32 *)(p) = d; -#else -#define GetUi32(p) ((p)[0] | ((UInt32)(p)[1] << 8) | ((UInt32)(p)[2] << 16) | ((UInt32)(p)[3] << 24)) -#define SetUi32(p, d) { UInt32 x = (d); (p)[0] = (Byte)x; (p)[1] = (Byte)(x >> 8); \ - (p)[2] = (Byte)(x >> 16); (p)[3] = (Byte)(x >> 24); } -#endif +void Aes_Encode32(const CAes *p, UInt32 *dest, const UInt32 *src) +{ + AesEncode32(dest, src, p->rkey, p->numRounds2); +} +void Aes_Decode32(const CAes *p, UInt32 *dest, const UInt32 *src) +{ + AesDecode32(dest, src, p->rkey, p->numRounds2); +} -void MY_FAST_CALL AesCbcInit(CAesCbc *cbc, const Byte *iv) +void AesCbc_Init(CAesCbc *p, const Byte *iv) { unsigned i; for (i = 0; i < 4; i++) - cbc->prev[i] = GetUi32(iv + i * 4); + p->prev[i] = GetUi32(iv + i * 4); } -UInt32 MY_FAST_CALL AesCbcEncode(CAesCbc *cbc, Byte *data, UInt32 size) +SizeT AesCbc_Encode(CAesCbc *p, Byte *data, SizeT size) { - UInt32 i; + SizeT i; if (size == 0) return 0; if (size < AES_BLOCK_SIZE) @@ -212,24 +215,24 @@ UInt32 MY_FAST_CALL AesCbcEncode(CAesCbc *cbc, Byte *data, UInt32 size) size -= AES_BLOCK_SIZE; for (i = 0; i <= size; i += AES_BLOCK_SIZE, data += AES_BLOCK_SIZE) { - cbc->prev[0] ^= GetUi32(data); - cbc->prev[1] ^= GetUi32(data + 4); - cbc->prev[2] ^= GetUi32(data + 8); - cbc->prev[3] ^= GetUi32(data + 12); + p->prev[0] ^= GetUi32(data); + p->prev[1] ^= GetUi32(data + 4); + p->prev[2] ^= GetUi32(data + 8); + p->prev[3] ^= GetUi32(data + 12); - AesEncode32(cbc->prev, cbc->prev, cbc->aes.rkey, cbc->aes.numRounds2); + AesEncode32(p->prev, p->prev, p->aes.rkey, p->aes.numRounds2); - SetUi32(data, cbc->prev[0]); - SetUi32(data + 4, cbc->prev[1]); - SetUi32(data + 8, cbc->prev[2]); - SetUi32(data + 12, cbc->prev[3]); + SetUi32(data, p->prev[0]); + SetUi32(data + 4, p->prev[1]); + SetUi32(data + 8, p->prev[2]); + SetUi32(data + 12, p->prev[3]); } return i; } -UInt32 MY_FAST_CALL AesCbcDecode(CAesCbc *cbc, Byte *data, UInt32 size) +SizeT AesCbc_Decode(CAesCbc *p, Byte *data, SizeT size) { - UInt32 i; + SizeT i; UInt32 in[4], out[4]; if (size == 0) return 0; @@ -243,17 +246,17 @@ UInt32 MY_FAST_CALL AesCbcDecode(CAesCbc *cbc, Byte *data, UInt32 size) in[2] = GetUi32(data + 8); in[3] = GetUi32(data + 12); - AesDecode32(in, out, cbc->aes.rkey, cbc->aes.numRounds2); + AesDecode32(out, in, p->aes.rkey, p->aes.numRounds2); - SetUi32(data, cbc->prev[0] ^ out[0]); - SetUi32(data + 4, cbc->prev[1] ^ out[1]); - SetUi32(data + 8, cbc->prev[2] ^ out[2]); - SetUi32(data + 12, cbc->prev[3] ^ out[3]); + SetUi32(data, p->prev[0] ^ out[0]); + SetUi32(data + 4, p->prev[1] ^ out[1]); + SetUi32(data + 8, p->prev[2] ^ out[2]); + SetUi32(data + 12, p->prev[3] ^ out[3]); - cbc->prev[0] = in[0]; - cbc->prev[1] = in[1]; - cbc->prev[2] = in[2]; - cbc->prev[3] = in[3]; + p->prev[0] = in[0]; + p->prev[1] = in[1]; + p->prev[2] = in[2]; + p->prev[3] = in[3]; } return i; } diff --git a/C/Aes.h b/C/Aes.h new file mode 100755 index 00000000..d5779788 --- /dev/null +++ b/C/Aes.h @@ -0,0 +1,48 @@ +/* Aes.h -- AES encryption / decryption +2008-03-26 +Igor Pavlov +Public domain */ + +#ifndef __AES_H +#define __AES_H + +#include "Types.h" + +#define AES_BLOCK_SIZE 16 + +typedef struct +{ + unsigned numRounds2; /* = numRounds / 2 */ + UInt32 rkey[(14 + 1) * 4]; +} CAes; + +/* Call AesGenTables one time before other AES functions */ +void AesGenTables(void); + +/* keySize = 16 or 24 or 32 (bytes) */ +void Aes_SetKeyEncode(CAes *p, const Byte *key, unsigned keySize); +void Aes_SetKeyDecode(CAes *p, const Byte *key, unsigned keySize); + +/* Aes_Encode32 and Aes_Decode32 functions work with little-endian words. + src and dest are pointers to 4 UInt32 words. + arc and dest can point to same block */ +void Aes_Encode32(const CAes *p, UInt32 *dest, const UInt32 *src); +void Aes_Decode32(const CAes *p, UInt32 *dest, const UInt32 *src); + +typedef struct +{ + UInt32 prev[4]; + CAes aes; +} CAesCbc; + +void AesCbc_Init(CAesCbc *p, const Byte *iv); /* iv size is AES_BLOCK_SIZE */ + +/* AesCbc_Encode and AesCbc_Decode: + if (res <= size): Filter have converted res bytes + if (res > size): Filter have not converted anything. And it needs at + least res = AES_BLOCK_SIZE bytes to convert one block */ + +SizeT AesCbc_Encode(CAesCbc *p, Byte *data, SizeT size); +SizeT AesCbc_Decode(CAesCbc *p, Byte *data, SizeT size); + +#endif @@ -1,4 +1,7 @@ -/* Alloc.c */ +/* Alloc.c -- Memory allocation functions +2008-03-13 +Igor Pavlov +Public domain */ #ifdef _WIN32 #include <windows.h> @@ -1,4 +1,7 @@ -/* Alloc.h */ +/* Alloc.h -- Memory allocation functions +2008-03-13 +Igor Pavlov +Public domain */ #ifndef __COMMON_ALLOC_H #define __COMMON_ALLOC_H diff --git a/C/Archive/7z/7z_C.dsp b/C/Archive/7z/7z.dsp index 9a040ad1..a0246af9 100755 --- a/C/Archive/7z/7z_C.dsp +++ b/C/Archive/7z/7z.dsp @@ -1,24 +1,24 @@ -# Microsoft Developer Studio Project File - Name="7z_C" - Package Owner=<4> +# Microsoft Developer Studio Project File - Name="7z" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Console Application" 0x0103 -CFG=7z_C - Win32 Debug +CFG=7z - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE -!MESSAGE NMAKE /f "7z_C.mak". +!MESSAGE NMAKE /f "7z.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "7z_C.mak" CFG="7z_C - Win32 Debug" +!MESSAGE NMAKE /f "7z.mak" CFG="7z - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE -!MESSAGE "7z_C - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "7z_C - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "7z - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "7z - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE # Begin Project @@ -28,7 +28,7 @@ CFG=7z_C - Win32 Debug CPP=cl.exe RSC=rc.exe -!IF "$(CFG)" == "7z_C - Win32 Release" +!IF "$(CFG)" == "7z - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 @@ -42,7 +42,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W4 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_LZMA_PROB32" /D "_LZMA_IN_CB" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD RSC /l 0x419 /d "NDEBUG" BSC32=bscmake.exe @@ -53,7 +53,7 @@ LINK32=link.exe # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release/7zDec.exe" /opt:NOWIN98 # SUBTRACT LINK32 /pdb:none -!ELSEIF "$(CFG)" == "7z_C - Win32 Debug" +!ELSEIF "$(CFG)" == "7z - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 @@ -67,7 +67,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W4 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_LZMA_PROB32" /D "_LZMA_IN_CB" /YX /FD /GZ /c +# ADD CPP /nologo /W4 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c # ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD RSC /l 0x419 /d "_DEBUG" BSC32=bscmake.exe @@ -81,29 +81,21 @@ LINK32=link.exe # Begin Target -# Name "7z_C - Win32 Release" -# Name "7z_C - Win32 Debug" -# Begin Group "LZMA" +# Name "7z - Win32 Release" +# Name "7z - Win32 Debug" +# Begin Group "Common" # PROP Default_Filter "" # Begin Source File -SOURCE=..\..\Compress\Lzma\LzmaDecode.c +SOURCE=..\..\7zBuf.c # End Source File # Begin Source File -SOURCE=..\..\Compress\Lzma\LzmaDecode.h +SOURCE=..\..\7zBuf.h # End Source File # Begin Source File -SOURCE=..\..\Compress\Lzma\LzmaTypes.h -# End Source File -# End Group -# Begin Group "Common" - -# PROP Default_Filter "" -# Begin Source File - SOURCE=..\..\7zCrc.c # End Source File # Begin Source File @@ -112,31 +104,31 @@ SOURCE=..\..\7zCrc.h # End Source File # Begin Source File -SOURCE=..\..\Types.h +SOURCE=..\..\Bcj2.c # End Source File -# End Group -# Begin Group "Branch" +# Begin Source File -# PROP Default_Filter "" +SOURCE=..\..\Bcj2.h +# End Source File # Begin Source File -SOURCE=..\..\Compress\Branch\BranchTypes.h +SOURCE=..\..\Bra.h # End Source File # Begin Source File -SOURCE=..\..\Compress\Branch\BranchX86.c +SOURCE=..\..\Bra86.c # End Source File # Begin Source File -SOURCE=..\..\Compress\Branch\BranchX86.h +SOURCE=..\..\LzmaDec.c # End Source File # Begin Source File -SOURCE=..\..\Compress\Branch\BranchX86_2.c +SOURCE=..\..\LzmaDec.h # End Source File # Begin Source File -SOURCE=..\..\Compress\Branch\BranchX86_2.h +SOURCE=..\..\Types.h # End Source File # End Group # Begin Source File @@ -149,14 +141,6 @@ SOURCE=.\7zAlloc.h # End Source File # Begin Source File -SOURCE=.\7zBuffer.c -# End Source File -# Begin Source File - -SOURCE=.\7zBuffer.h -# End Source File -# Begin Source File - SOURCE=.\7zDecode.c # End Source File # Begin Source File @@ -199,13 +183,5 @@ SOURCE=.\7zItem.h SOURCE=.\7zMain.c # End Source File -# Begin Source File - -SOURCE=.\7zMethodID.c -# End Source File -# Begin Source File - -SOURCE=.\7zMethodID.h -# End Source File # End Target # End Project diff --git a/C/Archive/7z/7z_C.dsw b/C/Archive/7z/7z.dsw index 6fd39621..848d13cb 100755 --- a/C/Archive/7z/7z_C.dsw +++ b/C/Archive/7z/7z.dsw @@ -3,7 +3,7 @@ Microsoft Developer Studio Workspace File, Format Version 6.00 ############################################################################### -Project: "7z_C"=.\7z_C.dsp - Package Owner=<4> +Project: "7z"=.\7z.dsp - Package Owner=<4> Package=<5> {{{ diff --git a/C/Archive/7z/7zAlloc.c b/C/Archive/7z/7zAlloc.c index 21bb30c7..1b48a258 100755 --- a/C/Archive/7z/7zAlloc.c +++ b/C/Archive/7z/7zAlloc.c @@ -1,4 +1,7 @@ -/* 7zAlloc.c */ +/* 7zAlloc.c -- Allocation functions +2008-03-28 +Igor Pavlov +Public domain */ #include <stdlib.h> #include "7zAlloc.h" @@ -11,13 +14,16 @@ #ifdef _WIN32 #include <windows.h> #endif + #include <stdio.h> int g_allocCount = 0; int g_allocCountTemp = 0; + #endif -void *SzAlloc(size_t size) +void *SzAlloc(void *p, size_t size) { + p = p; if (size == 0) return 0; #ifdef _SZ_ALLOC_DEBUG @@ -27,8 +33,9 @@ void *SzAlloc(size_t size) return malloc(size); } -void SzFree(void *address) +void SzFree(void *p, void *address) { + p = p; #ifdef _SZ_ALLOC_DEBUG if (address != 0) { @@ -39,8 +46,9 @@ void SzFree(void *address) free(address); } -void *SzAllocTemp(size_t size) +void *SzAllocTemp(void *p, size_t size) { + p = p; if (size == 0) return 0; #ifdef _SZ_ALLOC_DEBUG @@ -53,8 +61,9 @@ void *SzAllocTemp(size_t size) return malloc(size); } -void SzFreeTemp(void *address) +void SzFreeTemp(void *p, void *address) { + p = p; #ifdef _SZ_ALLOC_DEBUG if (address != 0) { diff --git a/C/Archive/7z/7zAlloc.h b/C/Archive/7z/7zAlloc.h index 4ca4170c..714ecf15 100755 --- a/C/Archive/7z/7zAlloc.h +++ b/C/Archive/7z/7zAlloc.h @@ -1,20 +1,17 @@ -/* 7zAlloc.h */ +/* 7zAlloc.h -- Allocation functions +2008-03-28 +Igor Pavlov +Public domain */ #ifndef __7Z_ALLOC_H #define __7Z_ALLOC_H #include <stddef.h> -typedef struct _ISzAlloc -{ - void *(*Alloc)(size_t size); - void (*Free)(void *address); /* address can be 0 */ -} ISzAlloc; +void *SzAlloc(void *p, size_t size); +void SzFree(void *p, void *address); -void *SzAlloc(size_t size); -void SzFree(void *address); - -void *SzAllocTemp(size_t size); -void SzFreeTemp(void *address); +void *SzAllocTemp(void *p, size_t size); +void SzFreeTemp(void *p, void *address); #endif diff --git a/C/Archive/7z/7zBuffer.c b/C/Archive/7z/7zBuffer.c deleted file mode 100755 index 3c4b71e8..00000000 --- a/C/Archive/7z/7zBuffer.c +++ /dev/null @@ -1,29 +0,0 @@ -/* 7zBuffer.c */ - -#include "7zBuffer.h" -#include "7zAlloc.h" - -void SzByteBufferInit(CSzByteBuffer *buffer) -{ - buffer->Capacity = 0; - buffer->Items = 0; -} - -int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size)) -{ - buffer->Capacity = newCapacity; - if (newCapacity == 0) - { - buffer->Items = 0; - return 1; - } - buffer->Items = (Byte *)allocFunc(newCapacity); - return (buffer->Items != 0); -} - -void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *)) -{ - freeFunc(buffer->Items); - buffer->Items = 0; - buffer->Capacity = 0; -} diff --git a/C/Archive/7z/7zBuffer.h b/C/Archive/7z/7zBuffer.h deleted file mode 100755 index 05c6d748..00000000 --- a/C/Archive/7z/7zBuffer.h +++ /dev/null @@ -1,19 +0,0 @@ -/* 7zBuffer.h */ - -#ifndef __7Z_BUFFER_H -#define __7Z_BUFFER_H - -#include <stddef.h> -#include "../../Types.h" - -typedef struct _CSzByteBuffer -{ - size_t Capacity; - Byte *Items; -}CSzByteBuffer; - -void SzByteBufferInit(CSzByteBuffer *buffer); -int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size)); -void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *)); - -#endif diff --git a/C/Archive/7z/7zDecode.c b/C/Archive/7z/7zDecode.c index aea893da..02a3c008 100755 --- a/C/Archive/7z/7zDecode.c +++ b/C/Archive/7z/7zDecode.c @@ -1,153 +1,114 @@ -/* 7zDecode.c */ +/* 7zDecode.c Decoding from 7z folder +2008-04-09 +Igor Pavlov +Copyright (c) 1999-2008 Igor Pavlov +Read 7zDecode.h for license options */ -#include <memory.h> +#include <string.h> #include "7zDecode.h" -#ifdef _SZ_ONE_DIRECTORY -#include "LzmaDecode.h" -#else -#include "../../Compress/Lzma/LzmaDecode.h" -#include "../../Compress/Branch/BranchX86.h" -#include "../../Compress/Branch/BranchX86_2.h" -#endif +#include "../../LzmaDec.h" +#include "../../Bra.h" +#include "../../Bcj2.h" #define k_Copy 0 #define k_LZMA 0x30101 #define k_BCJ 0x03030103 #define k_BCJ2 0x0303011B +/* #ifdef _LZMA_IN_CB +*/ -typedef struct _CLzmaInCallbackImp +static SRes SzDecodeLzma(CSzCoderInfo *coder, CFileSize inSize, ISzInStream *inStream, + Byte *outBuffer, size_t outSize, ISzAlloc *allocMain) { - ILzmaInCallback InCallback; - ISzInStream *InStream; - CFileSize Size; -} CLzmaInCallbackImp; + CLzmaDec state; + int res = SZ_OK; + size_t _inSize; + Byte *inBuf = NULL; -int LzmaReadImp(void *object, const unsigned char **buffer, SizeT *size) -{ - CLzmaInCallbackImp *cb = (CLzmaInCallbackImp *)object; - size_t processedSize; - SZ_RESULT res; - size_t curSize = (1 << 20); - if (curSize > cb->Size) - curSize = (size_t)cb->Size; - *size = 0; - res = cb->InStream->Read((void *)cb->InStream, (void **)buffer, curSize, &processedSize); - *size = (SizeT)processedSize; - if (processedSize > curSize) - return (int)SZE_FAIL; - cb->Size -= processedSize; - if (res == SZ_OK) - return 0; - return (int)res; -} + LzmaDec_Construct(&state); + RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain)); + state.dic = outBuffer; + state.dicBufSize = outSize; + LzmaDec_Init(&state); -#endif + _inSize = 0; -SZ_RESULT SzDecodeLzma(CCoderInfo *coder, CFileSize inSize, - #ifdef _LZMA_IN_CB - ISzInStream *inStream, - #else - const Byte *inBuffer, - #endif - Byte *outBuffer, size_t outSize, ISzAlloc *allocMain) -{ - #ifdef _LZMA_IN_CB - CLzmaInCallbackImp lzmaCallback; - #else - SizeT inProcessed; - #endif - - CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */ - int result; - SizeT outSizeProcessedLoc; - - #ifdef _LZMA_IN_CB - lzmaCallback.Size = inSize; - lzmaCallback.InStream = inStream; - lzmaCallback.InCallback.Read = LzmaReadImp; - #endif - - if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items, - (unsigned)coder->Properties.Capacity) != LZMA_RESULT_OK) - return SZE_FAIL; - - state.Probs = (CProb *)allocMain->Alloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb)); - if (state.Probs == 0) - return SZE_OUTOFMEMORY; - - #ifdef _LZMA_OUT_READ - if (state.Properties.DictionarySize == 0) - state.Dictionary = 0; - else + for (;;) { - state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize); - if (state.Dictionary == 0) + if (_inSize == 0) { - allocMain->Free(state.Probs); - return SZE_OUTOFMEMORY; + _inSize = (1 << 18); + if (_inSize > inSize) + _inSize = (size_t)(inSize); + res = inStream->Read((void *)inStream, (void **)&inBuf, &_inSize); + if (res != SZ_OK) + break; + inSize -= _inSize; } - } - LzmaDecoderInit(&state); - #endif - - result = LzmaDecode(&state, - #ifdef _LZMA_IN_CB - &lzmaCallback.InCallback, - #else - inBuffer, (SizeT)inSize, &inProcessed, - #endif - outBuffer, (SizeT)outSize, &outSizeProcessedLoc); - allocMain->Free(state.Probs); - #ifdef _LZMA_OUT_READ - allocMain->Free(state.Dictionary); - #endif - if (result == LZMA_RESULT_DATA_ERROR) - return SZE_DATA_ERROR; - if (result != LZMA_RESULT_OK) - return SZE_FAIL; - return (outSizeProcessedLoc == outSize) ? SZ_OK : SZE_DATA_ERROR; + + { + SizeT inProcessed = _inSize, dicPos = state.dicPos; + ELzmaStatus status; + res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); + _inSize -= inProcessed; + inBuf = (Byte *)inBuf + inProcessed; + if (res != SZ_OK) + break; + if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos)) + { + if (state.dicBufSize != outSize || _inSize != 0 || + (status != LZMA_STATUS_FINISHED_WITH_MARK && + status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) + res = SZ_ERROR_DATA; + break; + } + } + } + + LzmaDec_FreeProbs(&state, allocMain); + + return res; } -#ifdef _LZMA_IN_CB -SZ_RESULT SzDecodeCopy(CFileSize inSize, ISzInStream *inStream, Byte *outBuffer) +static SRes SzDecodeCopy(CFileSize inSize, ISzInStream *inStream, Byte *outBuffer) { while (inSize > 0) { void *inBuffer; - size_t processedSize, curSize = (1 << 18); + size_t curSize = (1 << 18); if (curSize > inSize) curSize = (size_t)(inSize); - RINOK(inStream->Read((void *)inStream, (void **)&inBuffer, curSize, &processedSize)); - if (processedSize == 0) - return SZE_DATA_ERROR; - if (processedSize > curSize) - return SZE_FAIL; - memcpy(outBuffer, inBuffer, processedSize); - outBuffer += processedSize; - inSize -= processedSize; + RINOK(inStream->Read((void *)inStream, (void **)&inBuffer, &curSize)); + if (curSize == 0) + return SZ_ERROR_INPUT_EOF; + memcpy(outBuffer, inBuffer, curSize); + outBuffer += curSize; + inSize -= curSize; } return SZ_OK; } +/* #endif +*/ #define IS_UNSUPPORTED_METHOD(m) ((m) != k_Copy && (m) != k_LZMA) #define IS_UNSUPPORTED_CODER(c) (IS_UNSUPPORTED_METHOD(c.MethodID) || c.NumInStreams != 1 || c.NumOutStreams != 1) #define IS_NO_BCJ(c) (c.MethodID != k_BCJ || c.NumInStreams != 1 || c.NumOutStreams != 1) #define IS_NO_BCJ2(c) (c.MethodID != k_BCJ2 || c.NumInStreams != 4 || c.NumOutStreams != 1) -SZ_RESULT CheckSupportedFolder(const CFolder *f) +SRes CheckSupportedFolder(const CSzFolder *f) { if (f->NumCoders < 1 || f->NumCoders > 4) - return SZE_NOTIMPL; + return SZ_ERROR_UNSUPPORTED; if (IS_UNSUPPORTED_CODER(f->Coders[0])) - return SZE_NOTIMPL; + return SZ_ERROR_UNSUPPORTED; if (f->NumCoders == 1) { if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0) - return SZE_NOTIMPL; + return SZ_ERROR_UNSUPPORTED; return SZ_OK; } if (f->NumCoders == 2) @@ -156,7 +117,7 @@ SZ_RESULT CheckSupportedFolder(const CFolder *f) f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 1 || f->BindPairs[0].InIndex != 1 || f->BindPairs[0].OutIndex != 0) - return SZE_NOTIMPL; + return SZ_ERROR_UNSUPPORTED; return SZ_OK; } if (f->NumCoders == 4) @@ -164,7 +125,7 @@ SZ_RESULT CheckSupportedFolder(const CFolder *f) if (IS_UNSUPPORTED_CODER(f->Coders[1]) || IS_UNSUPPORTED_CODER(f->Coders[2]) || IS_NO_BCJ2(f->Coders[3])) - return SZE_NOTIMPL; + return SZ_ERROR_UNSUPPORTED; if (f->NumPackStreams != 4 || f->PackStreams[0] != 2 || f->PackStreams[1] != 6 || @@ -174,10 +135,10 @@ SZ_RESULT CheckSupportedFolder(const CFolder *f) f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 || f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 || f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2) - return SZE_NOTIMPL; + return SZ_ERROR_UNSUPPORTED; return SZ_OK; } - return SZE_NOTIMPL; + return SZ_ERROR_UNSUPPORTED; } CFileSize GetSum(const CFileSize *values, UInt32 index) @@ -189,12 +150,16 @@ CFileSize GetSum(const CFileSize *values, UInt32 index) return sum; } -SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder, +SRes SzDecode2(const CFileSize *packSizes, const CSzFolder *folder, + /* #ifdef _LZMA_IN_CB + */ ISzInStream *inStream, CFileSize startPos, + /* #else const Byte *inBuffer, #endif + */ Byte *outBuffer, size_t outSize, ISzAlloc *allocMain, Byte *tempBuf[]) { @@ -207,7 +172,7 @@ SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder, for (ci = 0; ci < folder->NumCoders; ci++) { - CCoderInfo *coder = &folder->Coders[ci]; + CSzCoderInfo *coder = &folder->Coders[ci]; if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA) { @@ -226,57 +191,74 @@ SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder, Byte *temp; outSizeCur = (size_t)unpackSize; if (outSizeCur != unpackSize) - return SZE_OUTOFMEMORY; - temp = (Byte *)allocMain->Alloc(outSizeCur); + return SZ_ERROR_MEM; + temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur); if (temp == 0 && outSizeCur != 0) - return SZE_OUTOFMEMORY; + return SZ_ERROR_MEM; outBufCur = tempBuf[1 - ci] = temp; tempSizes[1 - ci] = outSizeCur; } else if (ci == 2) { - if (unpackSize > outSize) - return SZE_OUTOFMEMORY; + if (unpackSize > outSize) // check it + return SZ_ERROR_PARAM; // check it tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize); tempSize3 = outSizeCur = (size_t)unpackSize; } else - return SZE_NOTIMPL; + return SZ_ERROR_UNSUPPORTED; } offset = GetSum(packSizes, si); inSize = packSizes[si]; + /* #ifdef _LZMA_IN_CB - RINOK(inStream->Seek(inStream, startPos + offset)); + */ + RINOK(inStream->Seek(inStream, startPos + offset, SZ_SEEK_SET)); + /* #endif + */ if (coder->MethodID == k_Copy) { - if (inSize != outSizeCur) - return SZE_DATA_ERROR; + if (inSize != outSizeCur) // check it + return SZ_ERROR_DATA; + /* #ifdef _LZMA_IN_CB + */ RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); + /* #else memcpy(outBufCur, inBuffer + (size_t)offset, (size_t)inSize); #endif + */ } else { - SZ_RESULT res = SzDecodeLzma(coder, inSize, - #ifdef _LZMA_IN_CB + /* + #ifdef _LZMA_IN_CB + */ + SRes res = SzDecodeLzma(coder, inSize, inStream, - #else - inBuffer + (size_t)offset, - #endif outBufCur, outSizeCur, allocMain); - RINOK(res) + /* + #else + SizeT lzmaOutSizeT = outSizeCur; + SizeT lzmaInSizeT = (SizeT)inSize; + SRes res = LzmaDecode(outBufCur, &lzmaOutSizeT, + inBuffer + (size_t)offset, &lzmaInSizeT, + coder->Props.Items, (unsigned)coder->Props.size, LZMA_FINISH_BYTE, allocMain); + #endif + */ + + RINOK(res); } } else if (coder->MethodID == k_BCJ) { UInt32 state; if (ci != 1) - return SZE_NOTIMPL; + return SZ_ERROR_UNSUPPORTED; x86_Convert_Init(state); x86_Convert(outBuffer, outSize, 0, &state, 0); } @@ -284,58 +266,74 @@ SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder, { CFileSize offset = GetSum(packSizes, 1); CFileSize s3Size = packSizes[1]; - SZ_RESULT res; + SRes res; if (ci != 3) - return SZE_NOTIMPL; + return SZ_ERROR_UNSUPPORTED; + /* #ifdef _LZMA_IN_CB - RINOK(inStream->Seek(inStream, startPos + offset)); + */ + RINOK(inStream->Seek(inStream, startPos + offset, SZ_SEEK_SET)); tempSizes[2] = (size_t)s3Size; if (tempSizes[2] != s3Size) - return SZE_OUTOFMEMORY; - tempBuf[2] = (Byte *)allocMain->Alloc(tempSizes[2]); + return SZ_ERROR_MEM; + tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]); if (tempBuf[2] == 0 && tempSizes[2] != 0) - return SZE_OUTOFMEMORY; + return SZ_ERROR_MEM; res = SzDecodeCopy(s3Size, inStream, tempBuf[2]); RINOK(res) + /* #endif + */ - res = x86_2_Decode( + res = Bcj2_Decode( tempBuf3, tempSize3, tempBuf[0], tempSizes[0], tempBuf[1], tempSizes[1], + /* #ifdef _LZMA_IN_CB + */ tempBuf[2], tempSizes[2], + /* #else inBuffer + (size_t)offset, (size_t)s3Size, #endif + */ outBuffer, outSize); RINOK(res) } else - return SZE_NOTIMPL; + return SZ_ERROR_UNSUPPORTED; } return SZ_OK; } -SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder, +SRes SzDecode(const CFileSize *packSizes, const CSzFolder *folder, + /* #ifdef _LZMA_IN_CB + */ ISzInStream *inStream, CFileSize startPos, + /* #else const Byte *inBuffer, #endif + */ Byte *outBuffer, size_t outSize, ISzAlloc *allocMain) { Byte *tempBuf[3] = { 0, 0, 0}; int i; - SZ_RESULT res = SzDecode2(packSizes, folder, + SRes res = SzDecode2(packSizes, folder, + /* #ifdef _LZMA_IN_CB + */ inStream, startPos, + /* #else inBuffer, #endif + */ outBuffer, outSize, allocMain, tempBuf); for (i = 0; i < 3; i++) - allocMain->Free(tempBuf[i]); + IAlloc_Free(allocMain, tempBuf[i]); return res; } diff --git a/C/Archive/7z/7zDecode.h b/C/Archive/7z/7zDecode.h index 175896ef..5b0996d7 100755 --- a/C/Archive/7z/7zDecode.h +++ b/C/Archive/7z/7zDecode.h @@ -1,20 +1,26 @@ -/* 7zDecode.h */ +/* 7zDecode.h -- Decoding from 7z folder +2008-04-09 +Igor Pavlov +Copyright (c) 1999-2008 Igor Pavlov +Read 7zItem.h for license options */ #ifndef __7Z_DECODE_H #define __7Z_DECODE_H #include "7zItem.h" -#include "7zAlloc.h" -#ifdef _LZMA_IN_CB + #include "7zIn.h" -#endif -SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder, +SRes SzDecode(const CFileSize *packSizes, const CSzFolder *folder, + /* #ifdef _LZMA_IN_CB + */ ISzInStream *stream, CFileSize startPos, + /* #else const Byte *inBuffer, #endif + */ Byte *outBuffer, size_t outSize, ISzAlloc *allocMain); #endif diff --git a/C/Archive/7z/7zExtract.c b/C/Archive/7z/7zExtract.c index 1760a3ce..40b592aa 100755 --- a/C/Archive/7z/7zExtract.c +++ b/C/Archive/7z/7zExtract.c @@ -1,12 +1,16 @@ -/* 7zExtract.c */ +/* 7zExtract.c -- Extracting from 7z archive +2008-04-09 +Igor Pavlov +Copyright (c) 1999-2008 Igor Pavlov +Read 7zExtract.h for license options */ #include "7zExtract.h" #include "7zDecode.h" #include "../../7zCrc.h" -SZ_RESULT SzExtract( +SRes SzAr_Extract( + const CSzArEx *p, ISzInStream *inStream, - CArchiveDatabaseEx *db, UInt32 fileIndex, UInt32 *blockIndex, Byte **outBuffer, @@ -16,13 +20,13 @@ SZ_RESULT SzExtract( ISzAlloc *allocMain, ISzAlloc *allocTemp) { - UInt32 folderIndex = db->FileIndexToFolderIndexMap[fileIndex]; - SZ_RESULT res = SZ_OK; + UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex]; + SRes res = SZ_OK; *offset = 0; *outSizeProcessed = 0; if (folderIndex == (UInt32)-1) { - allocMain->Free(*outBuffer); + IAlloc_Free(allocMain, *outBuffer); *blockIndex = folderIndex; *outBuffer = 0; *outBufferSize = 0; @@ -31,87 +35,60 @@ SZ_RESULT SzExtract( if (*outBuffer == 0 || *blockIndex != folderIndex) { - CFolder *folder = db->Database.Folders + folderIndex; - CFileSize unPackSizeSpec = SzFolderGetUnPackSize(folder); + CSzFolder *folder = p->db.Folders + folderIndex; + CFileSize unPackSizeSpec = SzFolder_GetUnPackSize(folder); size_t unPackSize = (size_t)unPackSizeSpec; - CFileSize startOffset = SzArDbGetFolderStreamPos(db, folderIndex, 0); - #ifndef _LZMA_IN_CB - Byte *inBuffer = 0; - size_t processedSize; - CFileSize packSizeSpec; - size_t packSize; - RINOK(SzArDbGetFolderFullPackSize(db, folderIndex, &packSizeSpec)); - packSize = (size_t)packSizeSpec; - if (packSize != packSizeSpec) - return SZE_OUTOFMEMORY; - #endif + CFileSize startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0); + if (unPackSize != unPackSizeSpec) - return SZE_OUTOFMEMORY; + return SZ_ERROR_MEM; *blockIndex = folderIndex; - allocMain->Free(*outBuffer); + IAlloc_Free(allocMain, *outBuffer); *outBuffer = 0; - RINOK(inStream->Seek(inStream, startOffset)); + RINOK(inStream->Seek(inStream, startOffset, SZ_SEEK_SET)); - #ifndef _LZMA_IN_CB - if (packSize != 0) - { - inBuffer = (Byte *)allocTemp->Alloc(packSize); - if (inBuffer == 0) - return SZE_OUTOFMEMORY; - } - res = inStream->Read(inStream, inBuffer, packSize, &processedSize); - if (res == SZ_OK && processedSize != packSize) - res = SZE_FAIL; - #endif if (res == SZ_OK) { *outBufferSize = unPackSize; if (unPackSize != 0) { - *outBuffer = (Byte *)allocMain->Alloc(unPackSize); + *outBuffer = (Byte *)IAlloc_Alloc(allocMain, unPackSize); if (*outBuffer == 0) - res = SZE_OUTOFMEMORY; + res = SZ_ERROR_MEM; } if (res == SZ_OK) { - res = SzDecode(db->Database.PackSizes + - db->FolderStartPackStreamIndex[folderIndex], folder, - #ifdef _LZMA_IN_CB + res = SzDecode(p->db.PackSizes + + p->FolderStartPackStreamIndex[folderIndex], folder, inStream, startOffset, - #else - inBuffer, - #endif *outBuffer, unPackSize, allocTemp); if (res == SZ_OK) { if (folder->UnPackCRCDefined) { if (CrcCalc(*outBuffer, unPackSize) != folder->UnPackCRC) - res = SZE_CRC_ERROR; + res = SZ_ERROR_CRC; } } } } - #ifndef _LZMA_IN_CB - allocTemp->Free(inBuffer); - #endif } if (res == SZ_OK) { UInt32 i; - CFileItem *fileItem = db->Database.Files + fileIndex; + CSzFileItem *fileItem = p->db.Files + fileIndex; *offset = 0; - for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++) - *offset += (UInt32)db->Database.Files[i].Size; + for(i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++) + *offset += (UInt32)p->db.Files[i].Size; *outSizeProcessed = (size_t)fileItem->Size; if (*offset + *outSizeProcessed > *outBufferSize) - return SZE_FAIL; + return SZ_ERROR_FAIL; { if (fileItem->IsFileCRCDefined) { if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC) - res = SZE_CRC_ERROR; + res = SZ_ERROR_CRC; } } } diff --git a/C/Archive/7z/7zExtract.h b/C/Archive/7z/7zExtract.h index e9a4fb4e..cd0e4f03 100755 --- a/C/Archive/7z/7zExtract.h +++ b/C/Archive/7z/7zExtract.h @@ -1,4 +1,8 @@ -/* 7zExtract.h */ +/* 7zExtract.h -- Extracting from 7z archive +2008-04-09 +Igor Pavlov +Copyright (c) 1999-2008 Igor Pavlov +Read 7zItem.h for license options */ #ifndef __7Z_EXTRACT_H #define __7Z_EXTRACT_H @@ -25,9 +29,9 @@ Free *outBuffer and set *outBuffer to 0, if you want to flush cache. */ -SZ_RESULT SzExtract( +SRes SzAr_Extract( + const CSzArEx *db, ISzInStream *inStream, - CArchiveDatabaseEx *db, UInt32 fileIndex, /* index of file */ UInt32 *blockIndex, /* index of solid block */ Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ diff --git a/C/Archive/7z/7zHeader.c b/C/Archive/7z/7zHeader.c index 3be4bc27..3edb8d00 100755 --- a/C/Archive/7z/7zHeader.c +++ b/C/Archive/7z/7zHeader.c @@ -1,4 +1,8 @@ -/* 7zHeader.c */ +/* 7zHeader.c -- 7z Headers +2008-04-09 +Igor Pavlov +Copyright (c) 1999-2008 Igor Pavlov +Read 7zHeader.h for license options */ #include "7zHeader.h" diff --git a/C/Archive/7z/7zHeader.h b/C/Archive/7z/7zHeader.h index 3e67cf57..9cd3e3dc 100755 --- a/C/Archive/7z/7zHeader.h +++ b/C/Archive/7z/7zHeader.h @@ -1,4 +1,7 @@ -/* 7zHeader.h */ +/* 7zHeader.h -- 7z Headers +2008-03-17 +Copyright (c) 1999-2008 Igor Pavlov +Read LzmaDec.h for license options */ #ifndef __7Z_HEADER_H #define __7Z_HEADER_H diff --git a/C/Archive/7z/7zIn.c b/C/Archive/7z/7zIn.c index ac25dbc7..b99a6ac7 100755 --- a/C/Archive/7z/7zIn.c +++ b/C/Archive/7z/7zIn.c @@ -1,28 +1,32 @@ -/* 7zIn.c */ +/* 7zIn.c -- 7z Input functions +2008-04-09 +Igor Pavlov +Copyright (c) 1999-2008 Igor Pavlov +Read 7zIn.h for license options */ #include "7zIn.h" #include "7zDecode.h" #include "../../7zCrc.h" -#define RINOM(x) { if((x) == 0) return SZE_OUTOFMEMORY; } +#define RINOM(x) { if((x) == 0) return SZ_ERROR_MEM; } -void SzArDbExInit(CArchiveDatabaseEx *db) +void SzArEx_Init(CSzArEx *p) { - SzArchiveDatabaseInit(&db->Database); - db->FolderStartPackStreamIndex = 0; - db->PackStreamStartPositions = 0; - db->FolderStartFileIndex = 0; - db->FileIndexToFolderIndexMap = 0; + SzAr_Init(&p->db); + p->FolderStartPackStreamIndex = 0; + p->PackStreamStartPositions = 0; + p->FolderStartFileIndex = 0; + p->FileIndexToFolderIndexMap = 0; } -void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *)) +void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc) { - freeFunc(db->FolderStartPackStreamIndex); - freeFunc(db->PackStreamStartPositions); - freeFunc(db->FolderStartFileIndex); - freeFunc(db->FileIndexToFolderIndexMap); - SzArchiveDatabaseFree(&db->Database, freeFunc); - SzArDbExInit(db); + IAlloc_Free(alloc, p->FolderStartPackStreamIndex); + IAlloc_Free(alloc, p->PackStreamStartPositions); + IAlloc_Free(alloc, p->FolderStartFileIndex); + IAlloc_Free(alloc, p->FileIndexToFolderIndexMap); + SzAr_Free(&p->db, alloc); + SzArEx_Init(p); } /* @@ -36,7 +40,7 @@ CFileSize GetFilePackSize(int fileIndex) const int folderIndex = FileIndexToFolderIndexMap[fileIndex]; if (folderIndex >= 0) { - const CFolder &folderInfo = Folders[folderIndex]; + const CSzFolder &folderInfo = Folders[folderIndex]; if (FolderStartFileIndex[folderIndex] == fileIndex) return GetFolderFullPackSize(folderIndex); } @@ -44,41 +48,41 @@ CFileSize GetFilePackSize(int fileIndex) const } */ -#define MY_ALLOC(T, p, size, allocFunc) { if ((size) == 0) p = 0; else \ - if ((p = (T *)allocFunc((size) * sizeof(T))) == 0) return SZE_OUTOFMEMORY; } +#define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \ + if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; } -SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size)) +static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc) { UInt32 startPos = 0; CFileSize startPosSize = 0; UInt32 i; UInt32 folderIndex = 0; UInt32 indexInFolder = 0; - MY_ALLOC(UInt32, db->FolderStartPackStreamIndex, db->Database.NumFolders, allocFunc); - for(i = 0; i < db->Database.NumFolders; i++) + MY_ALLOC(UInt32, p->FolderStartPackStreamIndex, p->db.NumFolders, alloc); + for (i = 0; i < p->db.NumFolders; i++) { - db->FolderStartPackStreamIndex[i] = startPos; - startPos += db->Database.Folders[i].NumPackStreams; + p->FolderStartPackStreamIndex[i] = startPos; + startPos += p->db.Folders[i].NumPackStreams; } - MY_ALLOC(CFileSize, db->PackStreamStartPositions, db->Database.NumPackStreams, allocFunc); + MY_ALLOC(CFileSize, p->PackStreamStartPositions, p->db.NumPackStreams, alloc); - for(i = 0; i < db->Database.NumPackStreams; i++) + for (i = 0; i < p->db.NumPackStreams; i++) { - db->PackStreamStartPositions[i] = startPosSize; - startPosSize += db->Database.PackSizes[i]; + p->PackStreamStartPositions[i] = startPosSize; + startPosSize += p->db.PackSizes[i]; } - MY_ALLOC(UInt32, db->FolderStartFileIndex, db->Database.NumFolders, allocFunc); - MY_ALLOC(UInt32, db->FileIndexToFolderIndexMap, db->Database.NumFiles, allocFunc); + MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders, alloc); + MY_ALLOC(UInt32, p->FileIndexToFolderIndexMap, p->db.NumFiles, alloc); - for (i = 0; i < db->Database.NumFiles; i++) + for (i = 0; i < p->db.NumFiles; i++) { - CFileItem *file = db->Database.Files + i; + CSzFileItem *file = p->db.Files + i; int emptyStream = !file->HasStream; if (emptyStream && indexInFolder == 0) { - db->FileIndexToFolderIndexMap[i] = (UInt32)-1; + p->FileIndexToFolderIndexMap[i] = (UInt32)-1; continue; } if (indexInFolder == 0) @@ -89,19 +93,19 @@ SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size)) */ for (;;) { - if (folderIndex >= db->Database.NumFolders) - return SZE_ARCHIVE_ERROR; - db->FolderStartFileIndex[folderIndex] = i; - if (db->Database.Folders[folderIndex].NumUnPackStreams != 0) + if (folderIndex >= p->db.NumFolders) + return SZ_ERROR_ARCHIVE; + p->FolderStartFileIndex[folderIndex] = i; + if (p->db.Folders[folderIndex].NumUnPackStreams != 0) break; folderIndex++; } } - db->FileIndexToFolderIndexMap[i] = folderIndex; + p->FileIndexToFolderIndexMap[i] = folderIndex; if (emptyStream) continue; indexInFolder++; - if (indexInFolder >= db->Database.Folders[folderIndex].NumUnPackStreams) + if (indexInFolder >= p->db.Folders[folderIndex].NumUnPackStreams) { folderIndex++; indexInFolder = 0; @@ -111,23 +115,23 @@ SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size)) } -CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder) +CFileSize SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder) { - return db->ArchiveInfo.DataStartPosition + - db->PackStreamStartPositions[db->FolderStartPackStreamIndex[folderIndex] + indexInFolder]; + return p->ArchiveInfo.DataStartPosition + + p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder]; } -int SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex, CFileSize *resSize) +int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, CFileSize *resSize) { - UInt32 packStreamIndex = db->FolderStartPackStreamIndex[folderIndex]; - CFolder *folder = db->Database.Folders + folderIndex; + UInt32 packStreamIndex = p->FolderStartPackStreamIndex[folderIndex]; + CSzFolder *folder = p->db.Folders + folderIndex; CFileSize size = 0; UInt32 i; for (i = 0; i < folder->NumPackStreams; i++) { - CFileSize t = size + db->Database.PackSizes[packStreamIndex + i]; - if (t < size) - return SZE_FAIL; + CFileSize t = size + p->db.PackSizes[packStreamIndex + i]; + if (t < size) // check it + return SZ_ERROR_FAIL; size = t; } *resSize = size; @@ -136,8 +140,8 @@ int SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex, CFil /* -SZ_RESULT SzReadTime(const CObjectVector<CSzByteBuffer> &dataVector, - CObjectVector<CFileItem> &files, UInt64 type) +SRes SzReadTime(const CObjectVector<CBuf> &dataVector, + CObjectVector<CSzFileItem> &files, UInt64 type) { CBoolVector boolVector; RINOK(ReadBoolVector2(files.Size(), boolVector)) @@ -145,9 +149,9 @@ SZ_RESULT SzReadTime(const CObjectVector<CSzByteBuffer> &dataVector, CStreamSwitch streamSwitch; RINOK(streamSwitch.Set(this, &dataVector)); - for(int i = 0; i < files.Size(); i++) + for (int i = 0; i < files.Size(); i++) { - CFileItem &file = files[i]; + CSzFileItem &file = files[i]; CArchiveFileTime fileTime; bool defined = boolVector[i]; if (defined) @@ -181,40 +185,31 @@ SZ_RESULT SzReadTime(const CObjectVector<CSzByteBuffer> &dataVector, } */ -SZ_RESULT SafeReadDirect(ISzInStream *inStream, Byte *data, size_t size) +static SRes SafeReadDirect(ISzInStream *inStream, Byte *data, size_t size) { - #ifdef _LZMA_IN_CB while (size > 0) { void *inBufferSpec; - size_t processedSize; + size_t processedSize = size; const Byte *inBuffer; - RINOK(inStream->Read(inStream, (void **)&inBufferSpec, size, &processedSize)); + RINOK(inStream->Read(inStream, (void **)&inBufferSpec, &processedSize)); inBuffer = (const Byte *)inBufferSpec; - if (processedSize == 0 || processedSize > size) - return SZE_FAIL; + if (processedSize == 0) + return SZ_ERROR_INPUT_EOF; size -= processedSize; do - { *data++ = *inBuffer++; - } while (--processedSize != 0); } - #else - size_t processedSize; - RINOK(inStream->Read(inStream, data, size, &processedSize)); - if (processedSize != size) - return SZE_FAIL; - #endif return SZ_OK; } -SZ_RESULT SafeReadDirectByte(ISzInStream *inStream, Byte *data) +static SRes SafeReadDirectByte(ISzInStream *inStream, Byte *data) { return SafeReadDirect(inStream, data, 1); } -SZ_RESULT SafeReadDirectUInt32(ISzInStream *inStream, UInt32 *value, UInt32 *crc) +static SRes SafeReadDirectUInt32(ISzInStream *inStream, UInt32 *value, UInt32 *crc) { int i; *value = 0; @@ -228,7 +223,7 @@ SZ_RESULT SafeReadDirectUInt32(ISzInStream *inStream, UInt32 *value, UInt32 *crc return SZ_OK; } -SZ_RESULT SafeReadDirectUInt64(ISzInStream *inStream, UInt64 *value, UInt32 *crc) +static SRes SafeReadDirectUInt64(ISzInStream *inStream, UInt64 *value, UInt32 *crc) { int i; *value = 0; @@ -242,7 +237,7 @@ SZ_RESULT SafeReadDirectUInt64(ISzInStream *inStream, UInt64 *value, UInt32 *crc return SZ_OK; } -int TestSignatureCandidate(Byte *testBytes) +static int TestSignatureCandidate(Byte *testBytes) { size_t i; for (i = 0; i < k7zSignatureSize; i++) @@ -257,16 +252,16 @@ typedef struct _CSzState size_t Size; }CSzData; -SZ_RESULT SzReadByte(CSzData *sd, Byte *b) +static SRes SzReadByte(CSzData *sd, Byte *b) { if (sd->Size == 0) - return SZE_ARCHIVE_ERROR; + return SZ_ERROR_ARCHIVE; sd->Size--; *b = *sd->Data++; return SZ_OK; } -SZ_RESULT SzReadBytes(CSzData *sd, Byte *data, size_t size) +static SRes SzReadBytes(CSzData *sd, Byte *data, size_t size) { size_t i; for (i = 0; i < size; i++) @@ -276,7 +271,7 @@ SZ_RESULT SzReadBytes(CSzData *sd, Byte *data, size_t size) return SZ_OK; } -SZ_RESULT SzReadUInt32(CSzData *sd, UInt32 *value) +static SRes SzReadUInt32(CSzData *sd, UInt32 *value) { int i; *value = 0; @@ -289,7 +284,7 @@ SZ_RESULT SzReadUInt32(CSzData *sd, UInt32 *value) return SZ_OK; } -SZ_RESULT SzReadNumber(CSzData *sd, UInt64 *value) +static SRes SzReadNumber(CSzData *sd, UInt64 *value) { Byte firstByte; Byte mask = 0x80; @@ -312,7 +307,7 @@ SZ_RESULT SzReadNumber(CSzData *sd, UInt64 *value) return SZ_OK; } -SZ_RESULT SzReadSize(CSzData *sd, CFileSize *value) +static SRes SzReadSize(CSzData *sd, CFileSize *value) { UInt64 value64; RINOK(SzReadNumber(sd, &value64)); @@ -320,40 +315,40 @@ SZ_RESULT SzReadSize(CSzData *sd, CFileSize *value) return SZ_OK; } -SZ_RESULT SzReadNumber32(CSzData *sd, UInt32 *value) +static SRes SzReadNumber32(CSzData *sd, UInt32 *value) { UInt64 value64; RINOK(SzReadNumber(sd, &value64)); if (value64 >= 0x80000000) - return SZE_NOTIMPL; + return SZ_ERROR_UNSUPPORTED; if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2))) - return SZE_NOTIMPL; + return SZ_ERROR_UNSUPPORTED; *value = (UInt32)value64; return SZ_OK; } -SZ_RESULT SzReadID(CSzData *sd, UInt64 *value) +static SRes SzReadID(CSzData *sd, UInt64 *value) { return SzReadNumber(sd, value); } -SZ_RESULT SzSkeepDataSize(CSzData *sd, UInt64 size) +static SRes SzSkeepDataSize(CSzData *sd, UInt64 size) { if (size > sd->Size) - return SZE_ARCHIVE_ERROR; + return SZ_ERROR_ARCHIVE; sd->Size -= (size_t)size; sd->Data += (size_t)size; return SZ_OK; } -SZ_RESULT SzSkeepData(CSzData *sd) +static SRes SzSkeepData(CSzData *sd) { UInt64 size; RINOK(SzReadNumber(sd, &size)); return SzSkeepDataSize(sd, size); } -SZ_RESULT SzReadArchiveProperties(CSzData *sd) +static SRes SzReadArchiveProperties(CSzData *sd) { for (;;) { @@ -366,7 +361,7 @@ SZ_RESULT SzReadArchiveProperties(CSzData *sd) return SZ_OK; } -SZ_RESULT SzWaitAttribute(CSzData *sd, UInt64 attribute) +static SRes SzWaitAttribute(CSzData *sd, UInt64 attribute) { for (;;) { @@ -375,17 +370,17 @@ SZ_RESULT SzWaitAttribute(CSzData *sd, UInt64 attribute) if (type == attribute) return SZ_OK; if (type == k7zIdEnd) - return SZE_ARCHIVE_ERROR; + return SZ_ERROR_ARCHIVE; RINOK(SzSkeepData(sd)); } } -SZ_RESULT SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, void * (*allocFunc)(size_t size)) +static SRes SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc) { Byte b = 0; Byte mask = 0; size_t i; - MY_ALLOC(Byte, *v, numItems, allocFunc); + MY_ALLOC(Byte, *v, numItems, alloc); for (i = 0; i < numItems; i++) { if (mask == 0) @@ -399,30 +394,30 @@ SZ_RESULT SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, void * (*allo return SZ_OK; } -SZ_RESULT SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, void * (*allocFunc)(size_t size)) +static SRes SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc) { Byte allAreDefined; size_t i; RINOK(SzReadByte(sd, &allAreDefined)); if (allAreDefined == 0) - return SzReadBoolVector(sd, numItems, v, allocFunc); - MY_ALLOC(Byte, *v, numItems, allocFunc); - for(i = 0; i < numItems; i++) + return SzReadBoolVector(sd, numItems, v, alloc); + MY_ALLOC(Byte, *v, numItems, alloc); + for (i = 0; i < numItems; i++) (*v)[i] = 1; return SZ_OK; } -SZ_RESULT SzReadHashDigests( +static SRes SzReadHashDigests( CSzData *sd, size_t numItems, Byte **digestsDefined, UInt32 **digests, - void * (*allocFunc)(size_t size)) + ISzAlloc *alloc) { size_t i; - RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, allocFunc)); - MY_ALLOC(UInt32, *digests, numItems, allocFunc); - for(i = 0; i < numItems; i++) + RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, alloc)); + MY_ALLOC(UInt32, *digests, numItems, alloc); + for (i = 0; i < numItems; i++) if ((*digestsDefined)[i]) { RINOK(SzReadUInt32(sd, (*digests) + i)); @@ -430,14 +425,14 @@ SZ_RESULT SzReadHashDigests( return SZ_OK; } -SZ_RESULT SzReadPackInfo( +static SRes SzReadPackInfo( CSzData *sd, CFileSize *dataOffset, UInt32 *numPackStreams, CFileSize **packSizes, Byte **packCRCsDefined, UInt32 **packCRCs, - void * (*allocFunc)(size_t size)) + ISzAlloc *alloc) { UInt32 i; RINOK(SzReadSize(sd, dataOffset)); @@ -445,9 +440,9 @@ SZ_RESULT SzReadPackInfo( RINOK(SzWaitAttribute(sd, k7zIdSize)); - MY_ALLOC(CFileSize, *packSizes, (size_t)*numPackStreams, allocFunc); + MY_ALLOC(CFileSize, *packSizes, (size_t)*numPackStreams, alloc); - for(i = 0; i < *numPackStreams; i++) + for (i = 0; i < *numPackStreams; i++) { RINOK(SzReadSize(sd, (*packSizes) + i)); } @@ -460,16 +455,16 @@ SZ_RESULT SzReadPackInfo( break; if (type == k7zIdCRC) { - RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, allocFunc)); + RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc)); continue; } RINOK(SzSkeepData(sd)); } if (*packCRCsDefined == 0) { - MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, allocFunc); - MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, allocFunc); - for(i = 0; i < *numPackStreams; i++) + MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, alloc); + MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, alloc); + for (i = 0; i < *numPackStreams; i++) { (*packCRCsDefined)[i] = 0; (*packCRCs)[i] = 0; @@ -478,14 +473,14 @@ SZ_RESULT SzReadPackInfo( return SZ_OK; } -SZ_RESULT SzReadSwitch(CSzData *sd) +static SRes SzReadSwitch(CSzData *sd) { Byte external; RINOK(SzReadByte(sd, &external)); - return (external == 0) ? SZ_OK: SZE_ARCHIVE_ERROR; + return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED; } -SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(size_t size)) +static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc) { UInt32 numCoders; UInt32 numBindPairs; @@ -496,15 +491,15 @@ SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)( RINOK(SzReadNumber32(sd, &numCoders)); folder->NumCoders = numCoders; - MY_ALLOC(CCoderInfo, folder->Coders, (size_t)numCoders, allocFunc); + MY_ALLOC(CSzCoderInfo, folder->Coders, (size_t)numCoders, alloc); for (i = 0; i < numCoders; i++) - SzCoderInfoInit(folder->Coders + i); + SzCoderInfo_Init(folder->Coders + i); for (i = 0; i < numCoders; i++) { Byte mainByte; - CCoderInfo *coder = folder->Coders + i; + CSzCoderInfo *coder = folder->Coders + i; { unsigned idSize, j; Byte longID[15]; @@ -512,7 +507,7 @@ SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)( idSize = (unsigned)(mainByte & 0xF); RINOK(SzReadBytes(sd, longID, idSize)); if (idSize > sizeof(coder->MethodID)) - return SZE_NOTIMPL; + return SZ_ERROR_UNSUPPORTED; coder->MethodID = 0; for (j = 0; j < idSize; j++) coder->MethodID |= (CMethodID)longID[idSize - 1 - j] << (8 * j); @@ -531,9 +526,9 @@ SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)( { UInt64 propertiesSize = 0; RINOK(SzReadNumber(sd, &propertiesSize)); - if (!SzByteBufferCreate(&coder->Properties, (size_t)propertiesSize, allocFunc)) - return SZE_OUTOFMEMORY; - RINOK(SzReadBytes(sd, coder->Properties.Items, (size_t)propertiesSize)); + if (!Buf_Create(&coder->Props, (size_t)propertiesSize, alloc)) + return SZ_ERROR_MEM; + RINOK(SzReadBytes(sd, coder->Props.data, (size_t)propertiesSize)); } } while ((mainByte & 0x80) != 0) @@ -561,7 +556,7 @@ SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)( folder->NumBindPairs = numBindPairs; - MY_ALLOC(CBindPair, folder->BindPairs, (size_t)numBindPairs, allocFunc); + MY_ALLOC(CBindPair, folder->BindPairs, (size_t)numBindPairs, alloc); for (i = 0; i < numBindPairs; i++) { @@ -573,32 +568,32 @@ SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)( numPackedStreams = numInStreams - (UInt32)numBindPairs; folder->NumPackStreams = numPackedStreams; - MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackedStreams, allocFunc); + MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackedStreams, alloc); if (numPackedStreams == 1) { UInt32 j; UInt32 pi = 0; for (j = 0; j < numInStreams; j++) - if (SzFolderFindBindPairForInStream(folder, j) < 0) + if (SzFolder_FindBindPairForInStream(folder, j) < 0) { folder->PackStreams[pi++] = j; break; } } else - for(i = 0; i < numPackedStreams; i++) + for (i = 0; i < numPackedStreams; i++) { RINOK(SzReadNumber32(sd, folder->PackStreams + i)); } return SZ_OK; } -SZ_RESULT SzReadUnPackInfo( +static SRes SzReadUnPackInfo( CSzData *sd, UInt32 *numFolders, - CFolder **folders, /* for allocFunc */ - void * (*allocFunc)(size_t size), + CSzFolder **folders, /* for alloc */ + ISzAlloc *alloc, ISzAlloc *allocTemp) { UInt32 i; @@ -607,28 +602,28 @@ SZ_RESULT SzReadUnPackInfo( { RINOK(SzReadSwitch(sd)); - MY_ALLOC(CFolder, *folders, (size_t)*numFolders, allocFunc); + MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc); - for(i = 0; i < *numFolders; i++) - SzFolderInit((*folders) + i); + for (i = 0; i < *numFolders; i++) + SzFolder_Init((*folders) + i); - for(i = 0; i < *numFolders; i++) + for (i = 0; i < *numFolders; i++) { - RINOK(SzGetNextFolderItem(sd, (*folders) + i, allocFunc)); + RINOK(SzGetNextFolderItem(sd, (*folders) + i, alloc)); } } RINOK(SzWaitAttribute(sd, k7zIdCodersUnPackSize)); - for(i = 0; i < *numFolders; i++) + for (i = 0; i < *numFolders; i++) { UInt32 j; - CFolder *folder = (*folders) + i; - UInt32 numOutStreams = SzFolderGetNumOutStreams(folder); + CSzFolder *folder = (*folders) + i; + UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder); - MY_ALLOC(CFileSize, folder->UnPackSizes, (size_t)numOutStreams, allocFunc); + MY_ALLOC(CFileSize, folder->UnPackSizes, (size_t)numOutStreams, alloc); - for(j = 0; j < numOutStreams; j++) + for (j = 0; j < numOutStreams; j++) { RINOK(SzReadSize(sd, folder->UnPackSizes + j)); } @@ -642,21 +637,21 @@ SZ_RESULT SzReadUnPackInfo( return SZ_OK; if (type == k7zIdCRC) { - SZ_RESULT res; + SRes res; Byte *crcsDefined = 0; UInt32 *crcs = 0; - res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp->Alloc); + res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp); if (res == SZ_OK) { - for(i = 0; i < *numFolders; i++) + for (i = 0; i < *numFolders; i++) { - CFolder *folder = (*folders) + i; + CSzFolder *folder = (*folders) + i; folder->UnPackCRCDefined = crcsDefined[i]; folder->UnPackCRC = crcs[i]; } } - allocTemp->Free(crcs); - allocTemp->Free(crcsDefined); + IAlloc_Free(allocTemp, crcs); + IAlloc_Free(allocTemp, crcsDefined); RINOK(res); continue; } @@ -664,10 +659,10 @@ SZ_RESULT SzReadUnPackInfo( } } -SZ_RESULT SzReadSubStreamsInfo( +static SRes SzReadSubStreamsInfo( CSzData *sd, UInt32 numFolders, - CFolder *folders, + CSzFolder *folders, UInt32 *numUnPackStreams, CFileSize **unPackSizes, Byte **digestsDefined, @@ -679,7 +674,7 @@ SZ_RESULT SzReadSubStreamsInfo( UInt32 si = 0; UInt32 numDigests = 0; - for(i = 0; i < numFolders; i++) + for (i = 0; i < numFolders; i++) folders[i].NumUnPackStreams = 1; *numUnPackStreams = numFolders; @@ -689,7 +684,7 @@ SZ_RESULT SzReadSubStreamsInfo( if (type == k7zIdNumUnPackStream) { *numUnPackStreams = 0; - for(i = 0; i < numFolders; i++) + for (i = 0; i < numFolders; i++) { UInt32 numStreams; RINOK(SzReadNumber32(sd, &numStreams)); @@ -713,15 +708,15 @@ SZ_RESULT SzReadSubStreamsInfo( } else { - *unPackSizes = (CFileSize *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(CFileSize)); + *unPackSizes = (CFileSize *)IAlloc_Alloc(allocTemp, (size_t)*numUnPackStreams * sizeof(CFileSize)); RINOM(*unPackSizes); - *digestsDefined = (Byte *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(Byte)); + *digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnPackStreams * sizeof(Byte)); RINOM(*digestsDefined); - *digests = (UInt32 *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(UInt32)); + *digests = (UInt32 *)IAlloc_Alloc(allocTemp, (size_t)*numUnPackStreams * sizeof(UInt32)); RINOM(*digests); } - for(i = 0; i < numFolders; i++) + for (i = 0; i < numFolders; i++) { /* v3.13 incorrectly worked with empty folders @@ -740,21 +735,21 @@ SZ_RESULT SzReadSubStreamsInfo( (*unPackSizes)[si++] = size; sum += size; } - (*unPackSizes)[si++] = SzFolderGetUnPackSize(folders + i) - sum; + (*unPackSizes)[si++] = SzFolder_GetUnPackSize(folders + i) - sum; } if (type == k7zIdSize) { RINOK(SzReadID(sd, &type)); } - for(i = 0; i < *numUnPackStreams; i++) + for (i = 0; i < *numUnPackStreams; i++) { (*digestsDefined)[i] = 0; (*digests)[i] = 0; } - for(i = 0; i < numFolders; i++) + for (i = 0; i < numFolders; i++) { UInt32 numSubstreams = folders[i].NumUnPackStreams; if (numSubstreams != 1 || !folders[i].UnPackCRCDefined) @@ -770,12 +765,12 @@ SZ_RESULT SzReadSubStreamsInfo( int digestIndex = 0; Byte *digestsDefined2 = 0; UInt32 *digests2 = 0; - SZ_RESULT res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp->Alloc); + SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp); if (res == SZ_OK) { for (i = 0; i < numFolders; i++) { - CFolder *folder = folders + i; + CSzFolder *folder = folders + i; UInt32 numSubstreams = folder->NumUnPackStreams; if (numSubstreams == 1 && folder->UnPackCRCDefined) { @@ -795,8 +790,8 @@ SZ_RESULT SzReadSubStreamsInfo( } } } - allocTemp->Free(digestsDefined2); - allocTemp->Free(digests2); + IAlloc_Free(allocTemp, digestsDefined2); + IAlloc_Free(allocTemp, digests2); RINOK(res); } else if (type == k7zIdEnd) @@ -810,15 +805,15 @@ SZ_RESULT SzReadSubStreamsInfo( } -SZ_RESULT SzReadStreamsInfo( +static SRes SzReadStreamsInfo( CSzData *sd, CFileSize *dataOffset, - CArchiveDatabase *db, + CSzAr *p, UInt32 *numUnPackStreams, CFileSize **unPackSizes, /* allocTemp */ Byte **digestsDefined, /* allocTemp */ UInt32 **digests, /* allocTemp */ - void * (*allocFunc)(size_t size), + ISzAlloc *alloc, ISzAlloc *allocTemp) { for (;;) @@ -826,45 +821,44 @@ SZ_RESULT SzReadStreamsInfo( UInt64 type; RINOK(SzReadID(sd, &type)); if ((UInt64)(int)type != type) - return SZE_FAIL; + return SZ_ERROR_UNSUPPORTED; switch((int)type) { case k7zIdEnd: return SZ_OK; case k7zIdPackInfo: { - RINOK(SzReadPackInfo(sd, dataOffset, &db->NumPackStreams, - &db->PackSizes, &db->PackCRCsDefined, &db->PackCRCs, allocFunc)); + RINOK(SzReadPackInfo(sd, dataOffset, &p->NumPackStreams, + &p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc)); break; } case k7zIdUnPackInfo: { - RINOK(SzReadUnPackInfo(sd, &db->NumFolders, &db->Folders, allocFunc, allocTemp)); + RINOK(SzReadUnPackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp)); break; } case k7zIdSubStreamsInfo: { - RINOK(SzReadSubStreamsInfo(sd, db->NumFolders, db->Folders, + RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders, numUnPackStreams, unPackSizes, digestsDefined, digests, allocTemp)); break; } default: - return SZE_FAIL; + return SZ_ERROR_UNSUPPORTED; } } } Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; -SZ_RESULT SzReadFileNames(CSzData *sd, UInt32 numFiles, CFileItem *files, - void * (*allocFunc)(size_t size)) +static SRes SzReadFileNames(CSzData *sd, UInt32 numFiles, CSzFileItem *files, ISzAlloc *alloc) { UInt32 i; - for(i = 0; i < numFiles; i++) + for (i = 0; i < numFiles; i++) { UInt32 len = 0; UInt32 pos = 0; - CFileItem *file = files + i; + CSzFileItem *file = files + i; while(pos + 2 <= sd->Size) { int numAdds; @@ -879,13 +873,13 @@ SZ_RESULT SzReadFileNames(CSzData *sd, UInt32 numFiles, CFileItem *files, { UInt32 c2; if (value >= 0xDC00) - return SZE_ARCHIVE_ERROR; + return SZ_ERROR_ARCHIVE; if (pos + 2 > sd->Size) - return SZE_ARCHIVE_ERROR; + return SZ_ERROR_ARCHIVE; c2 = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8)); pos += 2; if (c2 < 0xDC00 || c2 >= 0xE000) - return SZE_ARCHIVE_ERROR; + return SZ_ERROR_ARCHIVE; value = ((value - 0xD800) << 10) | (c2 - 0xDC00); } for (numAdds = 1; numAdds < 5; numAdds++) @@ -894,7 +888,7 @@ SZ_RESULT SzReadFileNames(CSzData *sd, UInt32 numFiles, CFileItem *files, len += numAdds; } - MY_ALLOC(char, file->Name, (size_t)len, allocFunc); + MY_ALLOC(char, file->Name, (size_t)len, alloc); len = 0; while(2 <= sd->Size) @@ -932,9 +926,9 @@ SZ_RESULT SzReadFileNames(CSzData *sd, UInt32 numFiles, CFileItem *files, return SZ_OK; } -SZ_RESULT SzReadHeader2( +static SRes SzReadHeader2( + CSzArEx *p, /* allocMain */ CSzData *sd, - CArchiveDatabaseEx *db, /* allocMain */ CFileSize **unPackSizes, /* allocTemp */ Byte **digestsDefined, /* allocTemp */ UInt32 **digests, /* allocTemp */ @@ -947,7 +941,7 @@ SZ_RESULT SzReadHeader2( UInt64 type; UInt32 numUnPackStreams = 0; UInt32 numFiles = 0; - CFileItem *files = 0; + CSzFileItem *files = 0; UInt32 numEmptyStreams = 0; UInt32 i; @@ -963,29 +957,29 @@ SZ_RESULT SzReadHeader2( if (type == k7zIdMainStreamsInfo) { RINOK(SzReadStreamsInfo(sd, - &db->ArchiveInfo.DataStartPosition, - &db->Database, + &p->ArchiveInfo.DataStartPosition, + &p->db, &numUnPackStreams, unPackSizes, digestsDefined, - digests, allocMain->Alloc, allocTemp)); - db->ArchiveInfo.DataStartPosition += db->ArchiveInfo.StartPositionAfterHeader; + digests, allocMain, allocTemp)); + p->ArchiveInfo.DataStartPosition += p->ArchiveInfo.StartPositionAfterHeader; RINOK(SzReadID(sd, &type)); } if (type == k7zIdEnd) return SZ_OK; if (type != k7zIdFilesInfo) - return SZE_ARCHIVE_ERROR; + return SZ_ERROR_ARCHIVE; RINOK(SzReadNumber32(sd, &numFiles)); - db->Database.NumFiles = numFiles; + p->db.NumFiles = numFiles; - MY_ALLOC(CFileItem, files, (size_t)numFiles, allocMain->Alloc); + MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain); - db->Database.Files = files; - for(i = 0; i < numFiles; i++) - SzFileInit(files + i); + p->db.Files = files; + for (i = 0; i < numFiles; i++) + SzFile_Init(files + i); for (;;) { @@ -1006,12 +1000,12 @@ SZ_RESULT SzReadHeader2( case k7zIdName: { RINOK(SzReadSwitch(sd)); - RINOK(SzReadFileNames(sd, numFiles, files, allocMain->Alloc)) + RINOK(SzReadFileNames(sd, numFiles, files, allocMain)) break; } case k7zIdEmptyStream: { - RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp->Alloc)); + RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp)); numEmptyStreams = 0; for (i = 0; i < numFiles; i++) if ((*emptyStreamVector)[i]) @@ -1020,16 +1014,16 @@ SZ_RESULT SzReadHeader2( } case k7zIdEmptyFile: { - RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp->Alloc)); + RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp)); break; } case k7zIdLastWriteTime: { - RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp->Alloc)); + RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp)); RINOK(SzReadSwitch(sd)); for (i = 0; i < numFiles; i++) { - CFileItem *f = &files[i]; + CSzFileItem *f = &files[i]; Byte defined = (*lwtVector)[i]; f->IsLastWriteTimeDefined = defined; f->LastWriteTime.Low = f->LastWriteTime.High = 0; @@ -1051,9 +1045,9 @@ SZ_RESULT SzReadHeader2( { UInt32 emptyFileIndex = 0; UInt32 sizeIndex = 0; - for(i = 0; i < numFiles; i++) + for (i = 0; i < numFiles; i++) { - CFileItem *file = files + i; + CSzFileItem *file = files + i; file->IsAnti = 0; if (*emptyStreamVector == 0) file->HasStream = 1; @@ -1079,12 +1073,12 @@ SZ_RESULT SzReadHeader2( } } } - return SzArDbExFill(db, allocMain->Alloc); + return SzArEx_Fill(p, allocMain); } -SZ_RESULT SzReadHeader( +static SRes SzReadHeader( + CSzArEx *p, CSzData *sd, - CArchiveDatabaseEx *db, ISzAlloc *allocMain, ISzAlloc *allocTemp) { @@ -1094,118 +1088,89 @@ SZ_RESULT SzReadHeader( Byte *emptyStreamVector = 0; Byte *emptyFileVector = 0; Byte *lwtVector = 0; - SZ_RESULT res = SzReadHeader2(sd, db, + SRes res = SzReadHeader2(p, sd, &unPackSizes, &digestsDefined, &digests, &emptyStreamVector, &emptyFileVector, &lwtVector, allocMain, allocTemp); - allocTemp->Free(unPackSizes); - allocTemp->Free(digestsDefined); - allocTemp->Free(digests); - allocTemp->Free(emptyStreamVector); - allocTemp->Free(emptyFileVector); - allocTemp->Free(lwtVector); + IAlloc_Free(allocTemp, unPackSizes); + IAlloc_Free(allocTemp, digestsDefined); + IAlloc_Free(allocTemp, digests); + IAlloc_Free(allocTemp, emptyStreamVector); + IAlloc_Free(allocTemp, emptyFileVector); + IAlloc_Free(allocTemp, lwtVector); return res; } -SZ_RESULT SzReadAndDecodePackedStreams2( +static SRes SzReadAndDecodePackedStreams2( ISzInStream *inStream, CSzData *sd, - CSzByteBuffer *outBuffer, + CBuf *outBuffer, CFileSize baseOffset, - CArchiveDatabase *db, + CSzAr *p, CFileSize **unPackSizes, Byte **digestsDefined, UInt32 **digests, - #ifndef _LZMA_IN_CB - Byte **inBuffer, - #endif ISzAlloc *allocTemp) { UInt32 numUnPackStreams = 0; CFileSize dataStartPos; - CFolder *folder; - #ifndef _LZMA_IN_CB - CFileSize packSize = 0; - UInt32 i = 0; - #endif + CSzFolder *folder; CFileSize unPackSize; - SZ_RESULT res; + SRes res; - RINOK(SzReadStreamsInfo(sd, &dataStartPos, db, + RINOK(SzReadStreamsInfo(sd, &dataStartPos, p, &numUnPackStreams, unPackSizes, digestsDefined, digests, - allocTemp->Alloc, allocTemp)); + allocTemp, allocTemp)); dataStartPos += baseOffset; - if (db->NumFolders != 1) - return SZE_ARCHIVE_ERROR; + if (p->NumFolders != 1) + return SZ_ERROR_ARCHIVE; - folder = db->Folders; - unPackSize = SzFolderGetUnPackSize(folder); + folder = p->Folders; + unPackSize = SzFolder_GetUnPackSize(folder); - RINOK(inStream->Seek(inStream, dataStartPos)); - - #ifndef _LZMA_IN_CB - for (i = 0; i < db->NumPackStreams; i++) - packSize += db->PackSizes[i]; + RINOK(inStream->Seek(inStream, dataStartPos, SZ_SEEK_SET)); - MY_ALLOC(Byte, *inBuffer, (size_t)packSize, allocTemp->Alloc); - - RINOK(SafeReadDirect(inStream, *inBuffer, (size_t)packSize)); - #endif - - if (!SzByteBufferCreate(outBuffer, (size_t)unPackSize, allocTemp->Alloc)) - return SZE_OUTOFMEMORY; + if (!Buf_Create(outBuffer, (size_t)unPackSize, allocTemp)) + return SZ_ERROR_MEM; - res = SzDecode(db->PackSizes, folder, - #ifdef _LZMA_IN_CB + res = SzDecode(p->PackSizes, folder, inStream, dataStartPos, - #else - *inBuffer, - #endif - outBuffer->Items, (size_t)unPackSize, allocTemp); - RINOK(res) + outBuffer->data, (size_t)unPackSize, allocTemp); + RINOK(res); if (folder->UnPackCRCDefined) - if (CrcCalc(outBuffer->Items, (size_t)unPackSize) != folder->UnPackCRC) - return SZE_FAIL; + if (CrcCalc(outBuffer->data, (size_t)unPackSize) != folder->UnPackCRC) + return SZ_ERROR_CRC; return SZ_OK; } -SZ_RESULT SzReadAndDecodePackedStreams( +static SRes SzReadAndDecodePackedStreams( ISzInStream *inStream, CSzData *sd, - CSzByteBuffer *outBuffer, + CBuf *outBuffer, CFileSize baseOffset, ISzAlloc *allocTemp) { - CArchiveDatabase db; + CSzAr p; CFileSize *unPackSizes = 0; Byte *digestsDefined = 0; UInt32 *digests = 0; - #ifndef _LZMA_IN_CB - Byte *inBuffer = 0; - #endif - SZ_RESULT res; - SzArchiveDatabaseInit(&db); + SRes res; + SzAr_Init(&p); res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset, - &db, &unPackSizes, &digestsDefined, &digests, - #ifndef _LZMA_IN_CB - &inBuffer, - #endif + &p, &unPackSizes, &digestsDefined, &digests, allocTemp); - SzArchiveDatabaseFree(&db, allocTemp->Free); - allocTemp->Free(unPackSizes); - allocTemp->Free(digestsDefined); - allocTemp->Free(digests); - #ifndef _LZMA_IN_CB - allocTemp->Free(inBuffer); - #endif + SzAr_Free(&p, allocTemp); + IAlloc_Free(allocTemp, unPackSizes); + IAlloc_Free(allocTemp, digestsDefined); + IAlloc_Free(allocTemp, digests); return res; } -SZ_RESULT SzArchiveOpen2( +static SRes SzArEx_Open2( + CSzArEx *p, ISzInStream *inStream, - CArchiveDatabaseEx *db, ISzAlloc *allocMain, ISzAlloc *allocTemp) { @@ -1217,22 +1182,23 @@ SZ_RESULT SzArchiveOpen2( UInt32 nextHeaderCRC; UInt32 crc = 0; CFileSize pos = 0; - CSzByteBuffer buffer; + CBuf buffer; CSzData sd; - SZ_RESULT res; + SRes res; - RINOK(SafeReadDirect(inStream, signature, k7zSignatureSize)); + if (SafeReadDirect(inStream, signature, k7zSignatureSize) != SZ_OK) + return SZ_ERROR_NO_ARCHIVE; if (!TestSignatureCandidate(signature)) - return SZE_ARCHIVE_ERROR; + return SZ_ERROR_NO_ARCHIVE; /* - db.Clear(); - db.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition; + p.Clear(); + p.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition; */ RINOK(SafeReadDirectByte(inStream, &version)); if (version != k7zMajorVersion) - return SZE_ARCHIVE_ERROR; + return SZ_ERROR_UNSUPPORTED; RINOK(SafeReadDirectByte(inStream, &version)); RINOK(SafeReadDirectUInt32(inStream, &crcFromArchive, &crc)); @@ -1243,72 +1209,69 @@ SZ_RESULT SzArchiveOpen2( RINOK(SafeReadDirectUInt32(inStream, &nextHeaderCRC, &crc)); pos = k7zStartHeaderSize; - db->ArchiveInfo.StartPositionAfterHeader = pos; + p->ArchiveInfo.StartPositionAfterHeader = pos; if (CRC_GET_DIGEST(crc) != crcFromArchive) - return SZE_ARCHIVE_ERROR; + return SZ_ERROR_CRC; if (nextHeaderSize == 0) return SZ_OK; - RINOK(inStream->Seek(inStream, (CFileSize)(pos + nextHeaderOffset))); + RINOK(inStream->Seek(inStream, (CFileSize)(pos + nextHeaderOffset), SZ_SEEK_SET)); - if (!SzByteBufferCreate(&buffer, (size_t)nextHeaderSize, allocTemp->Alloc)) - return SZE_OUTOFMEMORY; + if (!Buf_Create(&buffer, (size_t)nextHeaderSize, allocTemp)) + return SZ_ERROR_MEM; - res = SafeReadDirect(inStream, buffer.Items, (size_t)nextHeaderSize); + res = SafeReadDirect(inStream, buffer.data, (size_t)nextHeaderSize); if (res == SZ_OK) { - res = SZE_ARCHIVE_ERROR; - if (CrcCalc(buffer.Items, (UInt32)nextHeaderSize) == nextHeaderCRC) + res = SZ_ERROR_ARCHIVE; + if (CrcCalc(buffer.data, (size_t)nextHeaderSize) == nextHeaderCRC) { for (;;) { UInt64 type; - sd.Data = buffer.Items; - sd.Size = buffer.Capacity; + sd.Data = buffer.data; + sd.Size = buffer.size; res = SzReadID(&sd, &type); if (res != SZ_OK) break; if (type == k7zIdHeader) { - res = SzReadHeader(&sd, db, allocMain, allocTemp); + res = SzReadHeader(p, &sd, allocMain, allocTemp); break; } if (type != k7zIdEncodedHeader) { - res = SZE_ARCHIVE_ERROR; + res = SZ_ERROR_UNSUPPORTED; break; } { - CSzByteBuffer outBuffer; + CBuf outBuffer; + Buf_Init(&outBuffer); res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, - db->ArchiveInfo.StartPositionAfterHeader, + p->ArchiveInfo.StartPositionAfterHeader, allocTemp); if (res != SZ_OK) { - SzByteBufferFree(&outBuffer, allocTemp->Free); + Buf_Free(&outBuffer, allocTemp); break; } - SzByteBufferFree(&buffer, allocTemp->Free); - buffer.Items = outBuffer.Items; - buffer.Capacity = outBuffer.Capacity; + Buf_Free(&buffer, allocTemp); + buffer.data = outBuffer.data; + buffer.size = outBuffer.size; } } } } - SzByteBufferFree(&buffer, allocTemp->Free); + Buf_Free(&buffer, allocTemp); return res; } -SZ_RESULT SzArchiveOpen( - ISzInStream *inStream, - CArchiveDatabaseEx *db, - ISzAlloc *allocMain, - ISzAlloc *allocTemp) +SRes SzArEx_Open(CSzArEx *p, ISzInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp) { - SZ_RESULT res = SzArchiveOpen2(inStream, db, allocMain, allocTemp); + SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp); if (res != SZ_OK) - SzArDbExFree(db, allocMain->Free); + SzArEx_Free(p, allocMain); return res; } diff --git a/C/Archive/7z/7zIn.h b/C/Archive/7z/7zIn.h index 0b4ca08d..811bbb66 100755 --- a/C/Archive/7z/7zIn.h +++ b/C/Archive/7z/7zIn.h @@ -1,55 +1,63 @@ -/* 7zIn.h */ +/* 7zIn.h -- 7z Input functions +2008-05-05 +Igor Pavlov +Copyright (c) 1999-2008 Igor Pavlov +Read 7zItem.h for license options */ #ifndef __7Z_IN_H #define __7Z_IN_H #include "7zHeader.h" #include "7zItem.h" -#include "7zAlloc.h" - -typedef struct _CInArchiveInfo + +typedef struct { CFileSize StartPositionAfterHeader; CFileSize DataStartPosition; -}CInArchiveInfo; +} CInArchiveInfo; -typedef struct _CArchiveDatabaseEx +typedef struct { - CArchiveDatabase Database; + CSzAr db; CInArchiveInfo ArchiveInfo; UInt32 *FolderStartPackStreamIndex; CFileSize *PackStreamStartPositions; UInt32 *FolderStartFileIndex; UInt32 *FileIndexToFolderIndexMap; -}CArchiveDatabaseEx; +} CSzArEx; -void SzArDbExInit(CArchiveDatabaseEx *db); -void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *)); -CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder); -int SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex, CFileSize *resSize); +void SzArEx_Init(CSzArEx *p); +void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc); +CFileSize SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder); +int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, CFileSize *resSize); -typedef struct _ISzInStream +typedef enum { - #ifdef _LZMA_IN_CB - SZ_RESULT (*Read)( - void *object, /* pointer to ISzInStream itself */ - void **buffer, /* out: pointer to buffer with data */ - size_t maxRequiredSize, /* max required size to read */ - size_t *processedSize); /* real processed size. - processedSize can be less than maxRequiredSize. - If processedSize == 0, then there are no more - bytes in stream. */ - #else - SZ_RESULT (*Read)(void *object, void *buffer, size_t size, size_t *processedSize); - #endif - SZ_RESULT (*Seek)(void *object, CFileSize pos); + SZ_SEEK_SET = 0, + SZ_SEEK_CUR = 1, + SZ_SEEK_END = 2 +} ESzSeek; + +typedef struct +{ + SRes (*Read)(void *object, void **buf, size_t *size); + /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. + (output(*size) < input(*size)) is allowed */ + SRes (*Seek)(void *object, CFileSize pos, ESzSeek origin); } ISzInStream; -int SzArchiveOpen( - ISzInStream *inStream, - CArchiveDatabaseEx *db, - ISzAlloc *allocMain, - ISzAlloc *allocTemp); +/* +Errors: +SZ_ERROR_NO_ARCHIVE +SZ_ERROR_ARCHIVE +SZ_ERROR_UNSUPPORTED +SZ_ERROR_MEM +SZ_ERROR_CRC +SZ_ERROR_INPUT_EOF +SZ_ERROR_FAIL +*/ + +SRes SzArEx_Open(CSzArEx *p, ISzInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp); #endif diff --git a/C/Archive/7z/7zItem.c b/C/Archive/7z/7zItem.c index a88afe9a..7a5ad427 100755 --- a/C/Archive/7z/7zItem.c +++ b/C/Archive/7z/7zItem.c @@ -1,134 +1,130 @@ -/* 7zItem.c */ +/* 7zItem.c -- 7z Items +2008-04-09 +Igor Pavlov +Copyright (c) 1999-2008 Igor Pavlov +Read 7zItem.h for license options */ #include "7zItem.h" -#include "7zAlloc.h" -void SzCoderInfoInit(CCoderInfo *coder) +void SzCoderInfo_Init(CSzCoderInfo *p) { - SzByteBufferInit(&coder->Properties); + Buf_Init(&p->Props); } -void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p)) +void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc) { - SzByteBufferFree(&coder->Properties, freeFunc); - SzCoderInfoInit(coder); + Buf_Free(&p->Props, alloc); + SzCoderInfo_Init(p); } -void SzFolderInit(CFolder *folder) +void SzFolder_Init(CSzFolder *p) { - folder->NumCoders = 0; - folder->Coders = 0; - folder->NumBindPairs = 0; - folder->BindPairs = 0; - folder->NumPackStreams = 0; - folder->PackStreams = 0; - folder->UnPackSizes = 0; - folder->UnPackCRCDefined = 0; - folder->UnPackCRC = 0; - folder->NumUnPackStreams = 0; + p->Coders = 0; + p->BindPairs = 0; + p->PackStreams = 0; + p->UnPackSizes = 0; + p->NumCoders = 0; + p->NumBindPairs = 0; + p->NumPackStreams = 0; + p->UnPackCRCDefined = 0; + p->UnPackCRC = 0; + p->NumUnPackStreams = 0; } -void SzFolderFree(CFolder *folder, void (*freeFunc)(void *p)) +void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc) { UInt32 i; - for (i = 0; i < folder->NumCoders; i++) - SzCoderInfoFree(&folder->Coders[i], freeFunc); - freeFunc(folder->Coders); - freeFunc(folder->BindPairs); - freeFunc(folder->PackStreams); - freeFunc(folder->UnPackSizes); - SzFolderInit(folder); + if (p->Coders) + for (i = 0; i < p->NumCoders; i++) + SzCoderInfo_Free(&p->Coders[i], alloc); + IAlloc_Free(alloc, p->Coders); + IAlloc_Free(alloc, p->BindPairs); + IAlloc_Free(alloc, p->PackStreams); + IAlloc_Free(alloc, p->UnPackSizes); + SzFolder_Init(p); } -UInt32 SzFolderGetNumOutStreams(CFolder *folder) +UInt32 SzFolder_GetNumOutStreams(CSzFolder *p) { UInt32 result = 0; UInt32 i; - for (i = 0; i < folder->NumCoders; i++) - result += folder->Coders[i].NumOutStreams; + for (i = 0; i < p->NumCoders; i++) + result += p->Coders[i].NumOutStreams; return result; } -int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex) +int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex) { UInt32 i; - for(i = 0; i < folder->NumBindPairs; i++) - if (folder->BindPairs[i].InIndex == inStreamIndex) + for (i = 0; i < p->NumBindPairs; i++) + if (p->BindPairs[i].InIndex == inStreamIndex) return i; return -1; } -int SzFolderFindBindPairForOutStream(CFolder *folder, UInt32 outStreamIndex) +int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex) { UInt32 i; - for(i = 0; i < folder->NumBindPairs; i++) - if (folder->BindPairs[i].OutIndex == outStreamIndex) + for (i = 0; i < p->NumBindPairs; i++) + if (p->BindPairs[i].OutIndex == outStreamIndex) return i; return -1; } -CFileSize SzFolderGetUnPackSize(CFolder *folder) +CFileSize SzFolder_GetUnPackSize(CSzFolder *p) { - int i = (int)SzFolderGetNumOutStreams(folder); + int i = (int)SzFolder_GetNumOutStreams(p); if (i == 0) return 0; for (i--; i >= 0; i--) - if (SzFolderFindBindPairForOutStream(folder, i) < 0) - return folder->UnPackSizes[i]; + if (SzFolder_FindBindPairForOutStream(p, i) < 0) + return p->UnPackSizes[i]; /* throw 1; */ return 0; } -/* -int FindPackStreamArrayIndex(int inStreamIndex) const +void SzFile_Init(CSzFileItem *p) { - for(int i = 0; i < PackStreams.Size(); i++) - if (PackStreams[i] == inStreamIndex) - return i; - return -1; -} -*/ - -void SzFileInit(CFileItem *fileItem) -{ - fileItem->IsFileCRCDefined = 0; - fileItem->HasStream = 1; - fileItem->IsDirectory = 0; - fileItem->IsAnti = 0; - fileItem->IsLastWriteTimeDefined = 0; - fileItem->Name = 0; + p->IsFileCRCDefined = 0; + p->HasStream = 1; + p->IsDirectory = 0; + p->IsAnti = 0; + p->IsLastWriteTimeDefined = 0; + p->Name = 0; } -void SzFileFree(CFileItem *fileItem, void (*freeFunc)(void *p)) +static void SzFile_Free(CSzFileItem *p, ISzAlloc *alloc) { - freeFunc(fileItem->Name); - SzFileInit(fileItem); + IAlloc_Free(alloc, p->Name); + SzFile_Init(p); } -void SzArchiveDatabaseInit(CArchiveDatabase *db) +void SzAr_Init(CSzAr *p) { - db->NumPackStreams = 0; - db->PackSizes = 0; - db->PackCRCsDefined = 0; - db->PackCRCs = 0; - db->NumFolders = 0; - db->Folders = 0; - db->NumFiles = 0; - db->Files = 0; + p->PackSizes = 0; + p->PackCRCsDefined = 0; + p->PackCRCs = 0; + p->Folders = 0; + p->Files = 0; + p->NumPackStreams = 0; + p->NumFolders = 0; + p->NumFiles = 0; } -void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *)) +void SzAr_Free(CSzAr *p, ISzAlloc *alloc) { UInt32 i; - for (i = 0; i < db->NumFolders; i++) - SzFolderFree(&db->Folders[i], freeFunc); - for (i = 0; i < db->NumFiles; i++) - SzFileFree(&db->Files[i], freeFunc); - freeFunc(db->PackSizes); - freeFunc(db->PackCRCsDefined); - freeFunc(db->PackCRCs); - freeFunc(db->Folders); - freeFunc(db->Files); - SzArchiveDatabaseInit(db); + if (p->Folders) + for (i = 0; i < p->NumFolders; i++) + SzFolder_Free(&p->Folders[i], alloc); + if (p->Files) + for (i = 0; i < p->NumFiles; i++) + SzFile_Free(&p->Files[i], alloc); + IAlloc_Free(alloc, p->PackSizes); + IAlloc_Free(alloc, p->PackCRCsDefined); + IAlloc_Free(alloc, p->PackCRCs); + IAlloc_Free(alloc, p->Folders); + IAlloc_Free(alloc, p->Files); + SzAr_Init(p); } diff --git a/C/Archive/7z/7zItem.h b/C/Archive/7z/7zItem.h index 05567bff..074a3a99 100755 --- a/C/Archive/7z/7zItem.h +++ b/C/Archive/7z/7zItem.h @@ -1,66 +1,79 @@ -/* 7zItem.h */ +/* 7zItem.h -- 7z Items +2008-05-01 +Igor Pavlov +Copyright (c) 1999-2008 Igor Pavlov +Read LzmaDec.h for license options */ #ifndef __7Z_ITEM_H #define __7Z_ITEM_H -#include "7zMethodID.h" -#include "7zHeader.h" -#include "7zBuffer.h" +#include "../../7zBuf.h" -typedef struct _CCoderInfo +/* #define _SZ_FILE_SIZE_32 */ +/* You can define _SZ_FILE_SIZE_32, if you don't need support for files larger than 4 GB*/ + +#ifdef _SZ_FILE_SIZE_32 +typedef UInt32 CFileSize; +#else +typedef UInt64 CFileSize; +#endif + +typedef UInt64 CMethodID; + +typedef struct { UInt32 NumInStreams; UInt32 NumOutStreams; CMethodID MethodID; - CSzByteBuffer Properties; -}CCoderInfo; + CBuf Props; +} CSzCoderInfo; -void SzCoderInfoInit(CCoderInfo *coder); -void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p)); +void SzCoderInfo_Init(CSzCoderInfo *p); +void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc); -typedef struct _CBindPair +typedef struct { UInt32 InIndex; UInt32 OutIndex; -}CBindPair; +} CBindPair; -typedef struct _CFolder +typedef struct { - UInt32 NumCoders; - CCoderInfo *Coders; - UInt32 NumBindPairs; + CSzCoderInfo *Coders; CBindPair *BindPairs; - UInt32 NumPackStreams; UInt32 *PackStreams; CFileSize *UnPackSizes; + UInt32 NumCoders; + UInt32 NumBindPairs; + UInt32 NumPackStreams; int UnPackCRCDefined; UInt32 UnPackCRC; UInt32 NumUnPackStreams; -}CFolder; +} CSzFolder; -void SzFolderInit(CFolder *folder); -CFileSize SzFolderGetUnPackSize(CFolder *folder); -int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex); -UInt32 SzFolderGetNumOutStreams(CFolder *folder); -CFileSize SzFolderGetUnPackSize(CFolder *folder); +void SzFolder_Init(CSzFolder *p); +CFileSize SzFolder_GetUnPackSize(CSzFolder *p); +int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex); +UInt32 SzFolder_GetNumOutStreams(CSzFolder *p); +CFileSize SzFolder_GetUnPackSize(CSzFolder *p); -typedef struct _CArchiveFileTime +typedef struct { UInt32 Low; UInt32 High; -} CArchiveFileTime; +} CNtfsFileTime; -typedef struct _CFileItem +typedef struct { - CArchiveFileTime LastWriteTime; + CNtfsFileTime LastWriteTime; /* CFileSize StartPos; UInt32 Attributes; */ CFileSize Size; - UInt32 FileCRC; char *Name; + UInt32 FileCRC; Byte IsFileCRCDefined; Byte HasStream; @@ -72,24 +85,23 @@ typedef struct _CFileItem int IsLastWriteTimeDefined; int IsStartPosDefined; */ -}CFileItem; +} CSzFileItem; -void SzFileInit(CFileItem *fileItem); +void SzFile_Init(CSzFileItem *p); -typedef struct _CArchiveDatabase +typedef struct { - UInt32 NumPackStreams; CFileSize *PackSizes; Byte *PackCRCsDefined; UInt32 *PackCRCs; + CSzFolder *Folders; + CSzFileItem *Files; + UInt32 NumPackStreams; UInt32 NumFolders; - CFolder *Folders; UInt32 NumFiles; - CFileItem *Files; -}CArchiveDatabase; - -void SzArchiveDatabaseInit(CArchiveDatabase *db); -void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *)); +} CSzAr; +void SzAr_Init(CSzAr *p); +void SzAr_Free(CSzAr *p, ISzAlloc *alloc); #endif diff --git a/C/Archive/7z/7zMain.c b/C/Archive/7z/7zMain.c index 0deef893..62f50689 100755 --- a/C/Archive/7z/7zMain.c +++ b/C/Archive/7z/7zMain.c @@ -1,8 +1,7 @@ -/* -7zMain.c -Test application for 7z Decoder -LZMA SDK 4.43 Copyright (c) 1999-2006 Igor Pavlov (2006-06-04) -*/ +/* 7zMain.c - Test application for 7z Decoder +2008-04-09 +Igor Pavlov +Public domain */ #include <stdio.h> #include <stdlib.h> @@ -18,6 +17,7 @@ LZMA SDK 4.43 Copyright (c) 1999-2006 Igor Pavlov (2006-06-04) #include "7zIn.h" #include "7zExtract.h" +#include "7zAlloc.h" #include "../../7zCrc.h" @@ -48,7 +48,7 @@ void ConvertNumberToString(CFileSize value, char *s) #define PERIOD_100 (PERIOD_4 * 25 - 1) #define PERIOD_400 (PERIOD_100 * 4 + 1) -void ConvertFileTimeToString(CArchiveFileTime *ft, char *s) +void ConvertFileTimeToString(CNtfsFileTime *ft, char *s) { unsigned year, mon, day, hour, min, sec; UInt64 v64 = ft->Low | ((UInt64)ft->High << 32); @@ -177,61 +177,59 @@ typedef struct _CFileInStream MY_FILE_HANDLE File; } CFileInStream; -#ifdef _LZMA_IN_CB #define kBufferSize (1 << 12) Byte g_Buffer[kBufferSize]; -SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxRequiredSize, size_t *processedSize) +SRes SzFileReadImp(void *object, void **buffer, size_t *size) { CFileInStream *s = (CFileInStream *)object; - size_t processedSizeLoc; - if (maxRequiredSize > kBufferSize) - maxRequiredSize = kBufferSize; - processedSizeLoc = MyReadFile(s->File, g_Buffer, maxRequiredSize); + if (*size > kBufferSize) + *size = kBufferSize; + *size = MyReadFile(s->File, g_Buffer, *size); *buffer = g_Buffer; - if (processedSize != 0) - *processedSize = processedSizeLoc; return SZ_OK; } -#else - -SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size, size_t *processedSize) -{ - CFileInStream *s = (CFileInStream *)object; - size_t processedSizeLoc = MyReadFile(s->File, buffer, size); - if (processedSize != 0) - *processedSize = processedSizeLoc; - return SZ_OK; -} - -#endif - -SZ_RESULT SzFileSeekImp(void *object, CFileSize pos) +SRes SzFileSeekImp(void *object, CFileSize pos, ESzSeek origin) { CFileInStream *s = (CFileInStream *)object; #ifdef USE_WINDOWS_FUNCTIONS { LARGE_INTEGER value; + DWORD moveMethod; value.LowPart = (DWORD)pos; value.HighPart = (LONG)((UInt64)pos >> 32); #ifdef _SZ_FILE_SIZE_32 /* VC 6.0 has bug with >> 32 shifts. */ value.HighPart = 0; #endif - value.LowPart = SetFilePointer(s->File, value.LowPart, &value.HighPart, FILE_BEGIN); + switch (origin) + { + case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break; + case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break; + case SZ_SEEK_END: moveMethod = FILE_END; break; + default: return SZ_ERROR_PARAM; + } + value.LowPart = SetFilePointer(s->File, value.LowPart, &value.HighPart, moveMethod); if (value.LowPart == 0xFFFFFFFF) - if(GetLastError() != NO_ERROR) - return SZE_FAIL; + if (GetLastError() != NO_ERROR) + return SZ_ERROR_FAIL; return SZ_OK; } #else - int res = fseek(s->File, (long)pos, SEEK_SET); - if (res == 0) - return SZ_OK; - return SZE_FAIL; + int moveMethod; + int res; + switch (origin) + { + case SZ_SEEK_SET: moveMethod = SEEK_SET; break; + case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break; + case SZ_SEEK_END: moveMethod = SEEK_END; break; + default: return SZ_ERROR_PARAM; + } + res = fseek(s->File, (long)pos, moveMethod ); + return (res == 0) ? SZ_OK : SZ_ERROR_FAIL; #endif } @@ -240,15 +238,15 @@ void PrintError(char *sz) printf("\nERROR: %s\n", sz); } -int main(int numargs, char *args[]) +int MY_CDECL main(int numargs, char *args[]) { CFileInStream archiveStream; - CArchiveDatabaseEx db; - SZ_RESULT res; + CSzArEx db; + SRes res; ISzAlloc allocImp; ISzAlloc allocTempImp; - printf("\n7z ANSI-C Decoder 4.48 Copyright (c) 1999-2007 Igor Pavlov 2007-06-21\n"); + printf("\n7z ANSI-C Decoder 4.58 Copyright (c) 1999-2008 Igor Pavlov 2008-04-09\n"); if (numargs == 1) { printf( @@ -267,7 +265,7 @@ int main(int numargs, char *args[]) archiveStream.File = #ifdef USE_WINDOWS_FUNCTIONS - CreateFile(args[2], GENERIC_READ, FILE_SHARE_READ, + CreateFileA(args[2], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (archiveStream.File == INVALID_HANDLE_VALUE) #else @@ -290,8 +288,8 @@ int main(int numargs, char *args[]) CrcGenerateTable(); - SzArDbExInit(&db); - res = SzArchiveOpen(&archiveStream.InStream, &db, &allocImp, &allocTempImp); + SzArEx_Init(&db); + res = SzArEx_Open(&db, &archiveStream.InStream, &allocImp, &allocTempImp); if (res == SZ_OK) { char *command = args[1]; @@ -308,9 +306,9 @@ int main(int numargs, char *args[]) if (listCommand) { UInt32 i; - for (i = 0; i < db.Database.NumFiles; i++) + for (i = 0; i < db.db.NumFiles; i++) { - CFileItem *f = db.Database.Files + i; + CSzFileItem *f = db.db.Files + i; char s[32], t[32]; ConvertNumberToString(f->Size, s); if (f->IsLastWriteTimeDefined) @@ -334,11 +332,11 @@ int main(int numargs, char *args[]) size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */ printf("\n"); - for (i = 0; i < db.Database.NumFiles; i++) + for (i = 0; i < db.db.NumFiles; i++) { size_t offset; size_t outSizeProcessed; - CFileItem *f = db.Database.Files + i; + CSzFileItem *f = db.db.Files + i; if (f->IsDirectory) printf("Directory "); else @@ -351,7 +349,7 @@ int main(int numargs, char *args[]) printf("\n"); continue; } - res = SzExtract(&archiveStream.InStream, &db, i, + res = SzAr_Extract(&db, &archiveStream.InStream, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocTempImp); @@ -372,7 +370,7 @@ int main(int numargs, char *args[]) outputHandle = #ifdef USE_WINDOWS_FUNCTIONS - CreateFile(fileName, GENERIC_WRITE, FILE_SHARE_READ, + CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (outputHandle == INVALID_HANDLE_VALUE) #else @@ -381,34 +379,34 @@ int main(int numargs, char *args[]) #endif { PrintError("can not open output file"); - res = SZE_FAIL; + res = SZ_ERROR_FAIL; break; } processedSize = MyWriteFile(outputHandle, outBuffer + offset, outSizeProcessed); if (processedSize != outSizeProcessed) { PrintError("can not write output file"); - res = SZE_FAIL; + res = SZ_ERROR_FAIL; break; } if (MyCloseFile(outputHandle)) { PrintError("can not close output file"); - res = SZE_FAIL; + res = SZ_ERROR_FAIL; break; } } printf("\n"); } - allocImp.Free(outBuffer); + IAlloc_Free(&allocImp, outBuffer); } else { PrintError("incorrect command"); - res = SZE_FAIL; + res = SZ_ERROR_FAIL; } } - SzArDbExFree(&db, allocImp.Free); + SzArEx_Free(&db, &allocImp); MyCloseFile(archiveStream.File); if (res == SZ_OK) @@ -416,11 +414,11 @@ int main(int numargs, char *args[]) printf("\nEverything is Ok\n"); return 0; } - if (res == (SZ_RESULT)SZE_NOTIMPL) + if (res == SZ_ERROR_UNSUPPORTED) PrintError("decoder doesn't support this archive"); - else if (res == (SZ_RESULT)SZE_OUTOFMEMORY) + else if (res == SZ_ERROR_MEM) PrintError("can not allocate memory"); - else if (res == (SZ_RESULT)SZE_CRC_ERROR) + else if (res == SZ_ERROR_CRC) PrintError("CRC error"); else printf("\nERROR #%d\n", res); diff --git a/C/Archive/7z/7zMethodID.c b/C/Archive/7z/7zMethodID.c deleted file mode 100755 index a7e825de..00000000 --- a/C/Archive/7z/7zMethodID.c +++ /dev/null @@ -1,10 +0,0 @@ -/* 7zMethodID.c */ - -#include "7zMethodID.h" - -/* -int AreMethodsEqual(CMethodID *a1, CMethodID *a2) -{ - return (*a1 == *a2) ? 1 : 0; -} -*/ diff --git a/C/Archive/7z/7zMethodID.h b/C/Archive/7z/7zMethodID.h deleted file mode 100755 index 57f22a50..00000000 --- a/C/Archive/7z/7zMethodID.h +++ /dev/null @@ -1,10 +0,0 @@ -/* 7zMethodID.h */ - -#ifndef __7Z_METHOD_ID_H -#define __7Z_METHOD_ID_H - -#include "../../Types.h" - -typedef UInt64 CMethodID; - -#endif diff --git a/C/Archive/7z/makefile b/C/Archive/7z/makefile index 6ea3119a..76fdec01 100755 --- a/C/Archive/7z/makefile +++ b/C/Archive/7z/makefile @@ -1,74 +1,30 @@ -PROG = 7zDec.exe - -!IFDEF CPU -LIBS = $(LIBS) bufferoverflowU.lib -CFLAGS = $(CFLAGS) -GS- -Zc:forScope -WX -GS- -Gy -W4 -!ENDIF - -!IFNDEF O -!IFDEF CPU -O=$(CPU) -!ELSE -O=O -!ENDIF -!ENDIF - -CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -D_LZMA_IN_CB -CFLAGS_O1 = $(CFLAGS) -O1 -CFLAGS_O2 = $(CFLAGS) -O2 - -LFLAGS = $(LFLAGS) -nologo -OPT:NOWIN98 -OPT:REF +MY_STATIC_LINK=1 -PROGPATH = $O\$(PROG) - -COMPL_O1 = $(CPP) $(CFLAGS_O1) $** -COMPL_O2 = $(CPP) $(CFLAGS_O2) $** -COMPL = $(CPP) $(CFLAGS_O1) $** +PROG = 7zDec.exe C_OBJS = \ + $O\7zBuf.obj \ $O\7zCrc.obj \ - + $O\LzmaDec.obj \ + $O\Bra86.obj \ + $O\Bcj2.obj \ 7Z_OBJS = \ $O\7zAlloc.obj \ - $O\7zBuffer.obj \ $O\7zDecode.obj \ $O\7zExtract.obj \ $O\7zHeader.obj \ $O\7zIn.obj \ $O\7zItem.obj \ $O\7zMain.obj \ - $O\7zMethodID.obj \ OBJS = \ $(7Z_OBJS) \ - $O\LzmaDecode.obj \ - $O\BranchX86.obj \ - $O\BranchX86_2.obj \ $(C_OBJS) \ -all: $(PROGPATH) - -clean: - -del /Q $(PROGPATH) $O\*.exe $O\*.dll $O\*.obj $O\*.lib $O\*.exp $O\*.res $O\*.pch - -$O: - if not exist "$O" mkdir "$O" - -$(PROGPATH): $O $(OBJS) - link $(LFLAGS) -out:$(PROGPATH) $(OBJS) $(LIBS) - +!include "../../../CPP/Build.mak" $(7Z_OBJS): $(*B).c - $(COMPL) -$O\LzmaDecode.obj: ../../Compress/Lzma/$(*B).c - $(COMPL_O2) - -$O\BranchX86.obj: ../../Compress/Branch/$(*B).c - $(COMPL_O2) - -$O\BranchX86_2.obj: ../../Compress/Branch/$(*B).c - $(COMPL_O2) - + $(COMPL_O1) $(C_OBJS): ../../$(*B).c $(COMPL_O2) diff --git a/C/Archive/7z/makefile.gcc b/C/Archive/7z/makefile.gcc index 664ac252..796412a1 100755 --- a/C/Archive/7z/makefile.gcc +++ b/C/Archive/7z/makefile.gcc @@ -2,9 +2,9 @@ PROG = 7zDec CXX = g++ LIB = RM = rm -f -CFLAGS = -c -O2 -Wall -D_LZMA_IN_CB +CFLAGS = -c -O2 -Wall -OBJS = 7zAlloc.o 7zBuffer.o 7zCrc.o 7zDecode.o 7zExtract.o 7zHeader.o 7zIn.o 7zItem.o 7zMain.o 7zMethodID.o LzmaDecode.o BranchX86.o BranchX86_2.o +OBJS = 7zAlloc.o 7zBuf.o 7zCrc.o 7zDecode.o 7zExtract.o 7zHeader.o 7zIn.o 7zItem.o 7zMain.o LzmaDec.o Bra86.o Bcj2.o all: $(PROG) @@ -14,8 +14,8 @@ $(PROG): $(OBJS) 7zAlloc.o: 7zAlloc.c $(CXX) $(CFLAGS) 7zAlloc.c -7zBuffer.o: 7zBuffer.c - $(CXX) $(CFLAGS) 7zBuffer.c +7zBuf.o: ../../7zBuf.c + $(CXX) $(CFLAGS) ../../7zBuf.c 7zCrc.o: ../../7zCrc.c $(CXX) $(CFLAGS) ../../7zCrc.c @@ -38,17 +38,14 @@ $(PROG): $(OBJS) 7zMain.o: 7zMain.c $(CXX) $(CFLAGS) 7zMain.c -7zMethodID.o: 7zMethodID.c - $(CXX) $(CFLAGS) 7zMethodID.c +LzmaDec.o: ../../LzmaDec.c + $(CXX) $(CFLAGS) ../../LzmaDec.c -LzmaDecode.o: ../../Compress/Lzma/LzmaDecode.c - $(CXX) $(CFLAGS) ../../Compress/Lzma/LzmaDecode.c +Bra86.o: ../../Bra86.c + $(CXX) $(CFLAGS) ../../Bra86.c -BranchX86.o: ../../Compress/Branch/BranchX86.c - $(CXX) $(CFLAGS) ../../Compress/Branch/BranchX86.c - -BranchX86_2.o: ../../Compress/Branch/BranchX86_2.c - $(CXX) $(CFLAGS) ../../Compress/Branch/BranchX86_2.c +Bcj2.o: ../../Bcj2.c + $(CXX) $(CFLAGS) ../../Bcj2.c clean: -$(RM) $(PROG) $(OBJS) diff --git a/C/Compress/Branch/BranchX86_2.c b/C/Bcj2.c index 241789a5..3a1d82fe 100755 --- a/C/Compress/Branch/BranchX86_2.c +++ b/C/Bcj2.c @@ -1,8 +1,11 @@ -// BranchX86_2.c +/* Bcj2.c -- Converter for x86 code (BCJ2) +2008-04-11 +Copyright (c) 1999-2008 Igor Pavlov +Read Bra.h for license options */ -#include "BranchX86_2.h" +#include "Bcj2.h" -#include "../../Alloc.h" +#include "Alloc.h" #ifdef _LZMA_PROB32 #define CProb UInt32 @@ -20,24 +23,18 @@ #define kBitModelTotal (1 << kNumBitModelTotalBits) #define kNumMoveBits 5 -#define RC_READ_BYTE (*Buffer++) +#define RC_READ_BYTE (*buffer++) +#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; } +#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \ + { int i; for(i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }} -#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \ - { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }} +#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; } -#define RC_TEST { if (Buffer == BufferLim) return BCJ2_RESULT_DATA_ERROR; } +#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) +#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE; +#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE; -#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2 - -#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; } - -#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound) -#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits; -#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits; -// #define UpdateBit0(p) Range = bound; *(p) = (CProb)(*(p) + ((kBitModelTotal - *(p)) >> kNumMoveBits)); -// #define UpdateBit1(p) Range -= bound; Code -= bound; *(p) = (CProb)(*(p) - (*(p) >> kNumMoveBits)); - -int x86_2_Decode( +int Bcj2_Decode( const Byte *buf0, SizeT size0, const Byte *buf1, SizeT size1, const Byte *buf2, SizeT size2, @@ -47,23 +44,27 @@ int x86_2_Decode( CProb p[256 + 2]; SizeT inPos = 0, outPos = 0; - const Byte *Buffer, *BufferLim; - UInt32 Range, Code; + const Byte *buffer, *bufferLim; + UInt32 range, code; Byte prevByte = 0; unsigned int i; for (i = 0; i < sizeof(p) / sizeof(p[0]); i++) p[i] = kBitModelTotal >> 1; - RC_INIT(buf3, size3); + + buffer = buf3; + bufferLim = buffer + size3; + RC_INIT2 if (outSize == 0) - return BCJ2_RESULT_OK; + return SZ_OK; for (;;) { Byte b; CProb *prob; UInt32 bound; + UInt32 ttt; SizeT limit = size0 - inPos; if (outSize - outPos < limit) @@ -91,21 +92,21 @@ int x86_2_Decode( else prob = p + 257; - IfBit0(prob) + IF_BIT_0(prob) { - UpdateBit0(prob) + UPDATE_0(prob) prevByte = b; } else { UInt32 dest; const Byte *v; - UpdateBit1(prob) + UPDATE_1(prob) if (b == 0xE8) { v = buf1; if (size1 < 4) - return BCJ2_RESULT_DATA_ERROR; + return SZ_ERROR_DATA; buf1 += 4; size1 -= 4; } @@ -113,7 +114,7 @@ int x86_2_Decode( { v = buf2; if (size2 < 4) - return BCJ2_RESULT_DATA_ERROR; + return SZ_ERROR_DATA; buf2 += 4; size2 -= 4; } @@ -131,5 +132,5 @@ int x86_2_Decode( outBuf[outPos++] = prevByte = (Byte)(dest >> 24); } } - return (outPos == outSize) ? BCJ2_RESULT_OK : BCJ2_RESULT_DATA_ERROR; + return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA; } diff --git a/C/Compress/Branch/BranchX86_2.h b/C/Bcj2.h index 4d861fa3..9dd81b5c 100755 --- a/C/Compress/Branch/BranchX86_2.h +++ b/C/Bcj2.h @@ -1,12 +1,12 @@ -// BranchX86_2.h +/* Bcj2.h -- Converter for x86 code (BCJ2) +2008-04-11 +Copyright (c) 1999-2008 Igor Pavlov +Read Bra.h for license options */ -#ifndef __BRANCHX86_2_H -#define __BRANCHX86_2_H +#ifndef __BCJ2_H +#define __BCJ2_H -#include "BranchTypes.h" - -#define BCJ2_RESULT_OK 0 -#define BCJ2_RESULT_DATA_ERROR 1 +#include "Types.h" /* Conditions: @@ -16,9 +16,13 @@ Conditions: If buf0 overlaps outBuf, there are two required conditions: 1) (buf0 >= outBuf) 2) (buf0 + size0 >= outBuf + FullOutputSize). + +Returns: + SZ_OK + SZ_ERROR_DATA - Data error */ -int x86_2_Decode( +int Bcj2_Decode( const Byte *buf0, SizeT size0, const Byte *buf1, SizeT size1, const Byte *buf2, SizeT size2, diff --git a/C/Bra.c b/C/Bra.c new file mode 100755 index 00000000..5683cb34 --- /dev/null +++ b/C/Bra.c @@ -0,0 +1,135 @@ +/* Bra.c -- converters for RISC code +2008-03-19 +Copyright (c) 1999-2008 Igor Pavlov +Read Bra.h for license options */ + +#include "Bra.h" + +SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +{ + SizeT i; + if (size < 4) + return 0; + size -= 4; + ip += 8; + for (i = 0; i <= size; i += 4) + { + if (data[i + 3] == 0xEB) + { + UInt32 dest; + UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]); + src <<= 2; + if (encoding) + dest = ip + (UInt32)i + src; + else + dest = src - (ip + (UInt32)i); + dest >>= 2; + data[i + 2] = (Byte)(dest >> 16); + data[i + 1] = (Byte)(dest >> 8); + data[i + 0] = (Byte)dest; + } + } + return i; +} + +SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +{ + SizeT i; + if (size < 4) + return 0; + size -= 4; + ip += 4; + for (i = 0; i <= size; i += 2) + { + if ((data[i + 1] & 0xF8) == 0xF0 && + (data[i + 3] & 0xF8) == 0xF8) + { + UInt32 dest; + UInt32 src = + (((UInt32)data[i + 1] & 0x7) << 19) | + ((UInt32)data[i + 0] << 11) | + (((UInt32)data[i + 3] & 0x7) << 8) | + (data[i + 2]); + + src <<= 1; + if (encoding) + dest = ip + (UInt32)i + src; + else + dest = src - (ip + (UInt32)i); + dest >>= 1; + + data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7)); + data[i + 0] = (Byte)(dest >> 11); + data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7)); + data[i + 2] = (Byte)dest; + i += 2; + } + } + return i; +} + +SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +{ + SizeT i; + if (size < 4) + return 0; + size -= 4; + for (i = 0; i <= size; i += 4) + { + if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1) + { + UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) | + ((UInt32)data[i + 1] << 16) | + ((UInt32)data[i + 2] << 8) | + ((UInt32)data[i + 3] & (~3)); + + UInt32 dest; + if (encoding) + dest = ip + (UInt32)i + src; + else + dest = src - (ip + (UInt32)i); + data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3)); + data[i + 1] = (Byte)(dest >> 16); + data[i + 2] = (Byte)(dest >> 8); + data[i + 3] &= 0x3; + data[i + 3] |= dest; + } + } + return i; +} + +SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +{ + UInt32 i; + if (size < 4) + return 0; + size -= 4; + for (i = 0; i <= size; i += 4) + { + if (data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00 || + data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0) + { + UInt32 src = + ((UInt32)data[i + 0] << 24) | + ((UInt32)data[i + 1] << 16) | + ((UInt32)data[i + 2] << 8) | + ((UInt32)data[i + 3]); + UInt32 dest; + + src <<= 2; + if (encoding) + dest = ip + i + src; + else + dest = src - (ip + i); + dest >>= 2; + + dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000; + + data[i + 0] = (Byte)(dest >> 24); + data[i + 1] = (Byte)(dest >> 16); + data[i + 2] = (Byte)(dest >> 8); + data[i + 3] = (Byte)dest; + } + } + return i; +} diff --git a/C/Bra.h b/C/Bra.h new file mode 100755 index 00000000..66800535 --- /dev/null +++ b/C/Bra.h @@ -0,0 +1,62 @@ +/* Bra.h -- Branch converters for executables +2008-03-19 +Copyright (c) 1999-2008 Igor Pavlov +Read LzmaDec.h for license options */ + +#ifndef __BRA_H +#define __BRA_H + +#include "Types.h" + +/* +These functions convert relative addresses to absolute addresses +in CALL instructions to increase the compression ratio. + + In: + data - data buffer + size - size of data + ip - current virtual Instruction Pinter (IP) value + state - state variable for x86 converter + encoding - 0 (for decoding), 1 (for encoding) + + Out: + state - state variable for x86 converter + + Returns: + The number of processed bytes. If you call these functions with multiple calls, + you must start next call with first byte after block of processed bytes. + + Type Endian Alignment LookAhead + + x86 little 1 4 + ARMT little 2 2 + ARM little 4 0 + PPC big 4 0 + SPARC big 4 0 + IA64 little 16 0 + + size must be >= Alignment + LookAhead, if it's not last block. + If (size < Alignment + LookAhead), converter returns 0. + + Example: + + UInt32 ip = 0; + for() + { + // size must be >= Alignment + LookAhead, if it's not last block + SizeT processed = Convert(data, size, ip, 1); + data += processed; + size -= processed; + ip += processed; + } +*/ + +#define x86_Convert_Init(state) { state = 0; } +SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding); +SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); +SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); +SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); +SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); +SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); + +#endif diff --git a/C/Compress/Branch/BranchX86.c b/C/Bra86.c index fd1d334e..62a1705b 100755 --- a/C/Compress/Branch/BranchX86.c +++ b/C/Bra86.c @@ -1,29 +1,32 @@ -/* BranchX86.c */ +/* Bra86.c -- converter for x86 code (BCJ) +2008-03-19 +Copyright (c) 1999-2008 Igor Pavlov +Read Bra.h for license options */ -#include "BranchX86.h" +#include "Bra.h" #define Test86MSByte(b) ((b) == 0 || (b) == 0xFF) const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0}; const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3}; -SizeT x86_Convert(Byte *buffer, SizeT endPos, UInt32 nowPos, UInt32 *prevMaskMix, int encoding) +SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding) { SizeT bufferPos = 0, prevPosT; - UInt32 prevMask = *prevMaskMix & 0x7; - if (endPos < 5) + UInt32 prevMask = *state & 0x7; + if (size < 5) return 0; - nowPos += 5; + ip += 5; prevPosT = (SizeT)0 - 1; for(;;) { - Byte *p = buffer + bufferPos; - Byte *limit = buffer + endPos - 4; + Byte *p = data + bufferPos; + Byte *limit = data + size - 4; for (; p < limit; p++) if ((*p & 0xFE) == 0xE8) break; - bufferPos = (SizeT)(p - buffer); + bufferPos = (SizeT)(p - data); if (p >= limit) break; prevPosT = bufferPos - prevPosT; @@ -55,9 +58,9 @@ SizeT x86_Convert(Byte *buffer, SizeT endPos, UInt32 nowPos, UInt32 *prevMaskMix Byte b; int index; if (encoding) - dest = (nowPos + (UInt32)bufferPos) + src; + dest = (ip + (UInt32)bufferPos) + src; else - dest = src - (nowPos + (UInt32)bufferPos); + dest = src - (ip + (UInt32)bufferPos); if (prevMask == 0) break; index = kMaskToBitNumber[prevMask] * 8; @@ -79,6 +82,6 @@ SizeT x86_Convert(Byte *buffer, SizeT endPos, UInt32 nowPos, UInt32 *prevMaskMix } } prevPosT = bufferPos - prevPosT; - *prevMaskMix = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7)); + *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7)); return bufferPos; } diff --git a/C/Compress/Branch/BranchIA64.c b/C/BraIA64.c index 009086b1..8e02cdea 100755 --- a/C/Compress/Branch/BranchIA64.c +++ b/C/BraIA64.c @@ -1,8 +1,11 @@ -/* BranchIA64.c */ +/* BraIA64.c -- converter for IA-64 code +2008-03-19 +Copyright (c) 1999-2008 Igor Pavlov +Read Bra.h for license options */ -#include "BranchIA64.h" +#include "Bra.h" -const Byte kBranchTable[32] = +static const Byte kBranchTable[32] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -10,10 +13,13 @@ const Byte kBranchTable[32] = 4, 4, 0, 0, 4, 4, 0, 0 }; -UInt32 IA64_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding) +SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) { - UInt32 i; - for (i = 0; i + 16 <= size; i += 16) + SizeT i; + if (size < 16) + return 0; + size -= 16; + for (i = 0; i <= size; i += 16) { UInt32 instrTemplate = data[i] & 0x1F; UInt32 mask = kBranchTable[instrTemplate]; @@ -30,13 +36,10 @@ UInt32 IA64_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding) bitRes = bitPos & 0x7; instruction = 0; for (j = 0; j < 6; j++) - instruction += (UInt64)(data[i + j + bytePos]) << (8 * j); + instruction += (UInt64)data[i + j + bytePos] << (8 * j); instNorm = instruction >> bitRes; - if (((instNorm >> 37) & 0xF) == 0x5 - && ((instNorm >> 9) & 0x7) == 0 - /* && (instNorm & 0x3F)== 0 */ - ) + if (((instNorm >> 37) & 0xF) == 0x5 && ((instNorm >> 9) & 0x7) == 0) { UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF); UInt32 dest; @@ -45,9 +48,9 @@ UInt32 IA64_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding) src <<= 4; if (encoding) - dest = nowPos + i + src; + dest = ip + (UInt32)i + src; else - dest = src - (nowPos + i); + dest = src - (ip + (UInt32)i); dest >>= 4; diff --git a/C/BwtSort.c b/C/BwtSort.c new file mode 100755 index 00000000..507046ad --- /dev/null +++ b/C/BwtSort.c @@ -0,0 +1,516 @@ +/* BwtSort.c -- BWT block sorting +2008-03-26 +Igor Pavlov +Public domain */ + +#include "BwtSort.h" +#include "Sort.h" + +/* #define BLOCK_SORT_USE_HEAP_SORT */ + +#define NO_INLINE MY_FAST_CALL + +/* Don't change it !!! */ +#define kNumHashBytes 2 +#define kNumHashValues (1 << (kNumHashBytes * 8)) + +/* kNumRefBitsMax must be < (kNumHashBytes * 8) = 16 */ +#define kNumRefBitsMax 12 + +#define BS_TEMP_SIZE kNumHashValues + +#ifdef BLOCK_SORT_EXTERNAL_FLAGS + +/* 32 Flags in UInt32 word */ +#define kNumFlagsBits 5 +#define kNumFlagsInWord (1 << kNumFlagsBits) +#define kFlagsMask (kNumFlagsInWord - 1) +#define kAllFlags 0xFFFFFFFF + +#else + +#define kNumBitsMax 20 +#define kIndexMask ((1 << kNumBitsMax) - 1) +#define kNumExtraBits (32 - kNumBitsMax) +#define kNumExtra0Bits (kNumExtraBits - 2) +#define kNumExtra0Mask ((1 << kNumExtra0Bits) - 1) + +#define SetFinishedGroupSize(p, size) \ + { *(p) |= ((((size) - 1) & kNumExtra0Mask) << kNumBitsMax); \ + if ((size) > (1 << kNumExtra0Bits)) { \ + *(p) |= 0x40000000; *((p) + 1) |= ((((size) - 1)>> kNumExtra0Bits) << kNumBitsMax); } } \ + +static void SetGroupSize(UInt32 *p, UInt32 size) +{ + if (--size == 0) + return; + *p |= 0x80000000 | ((size & kNumExtra0Mask) << kNumBitsMax); + if (size >= (1 << kNumExtra0Bits)) + { + *p |= 0x40000000; + p[1] |= ((size >> kNumExtra0Bits) << kNumBitsMax); + } +} + +#endif + +/* +SortGroup - is recursive Range-Sort function with HeapSort optimization for small blocks + "range" is not real range. It's only for optimization. +returns: 1 - if there are groups, 0 - no more groups +*/ + +UInt32 NO_INLINE SortGroup(UInt32 BlockSize, UInt32 NumSortedBytes, UInt32 groupOffset, UInt32 groupSize, int NumRefBits, UInt32 *Indices + #ifndef BLOCK_SORT_USE_HEAP_SORT + , UInt32 left, UInt32 range + #endif + ) +{ + UInt32 *ind2 = Indices + groupOffset; + UInt32 *Groups; + if (groupSize <= 1) + { + /* + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + SetFinishedGroupSize(ind2, 1); + #endif + */ + return 0; + } + Groups = Indices + BlockSize + BS_TEMP_SIZE; + if (groupSize <= ((UInt32)1 << NumRefBits) + #ifndef BLOCK_SORT_USE_HEAP_SORT + && groupSize <= range + #endif + ) + { + UInt32 *temp = Indices + BlockSize; + UInt32 j; + UInt32 mask, thereAreGroups, group, cg; + { + UInt32 gPrev; + UInt32 gRes = 0; + { + UInt32 sp = ind2[0] + NumSortedBytes; + if (sp >= BlockSize) sp -= BlockSize; + gPrev = Groups[sp]; + temp[0] = (gPrev << NumRefBits); + } + + for (j = 1; j < groupSize; j++) + { + UInt32 sp = ind2[j] + NumSortedBytes; + UInt32 g; + if (sp >= BlockSize) sp -= BlockSize; + g = Groups[sp]; + temp[j] = (g << NumRefBits) | j; + gRes |= (gPrev ^ g); + } + if (gRes == 0) + { + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + SetGroupSize(ind2, groupSize); + #endif + return 1; + } + } + + HeapSort(temp, groupSize); + mask = ((1 << NumRefBits) - 1); + thereAreGroups = 0; + + group = groupOffset; + cg = (temp[0] >> NumRefBits); + temp[0] = ind2[temp[0] & mask]; + + { + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 *Flags = Groups + BlockSize; + #else + UInt32 prevGroupStart = 0; + #endif + + for (j = 1; j < groupSize; j++) + { + UInt32 val = temp[j]; + UInt32 cgCur = (val >> NumRefBits); + + if (cgCur != cg) + { + cg = cgCur; + group = groupOffset + j; + + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + { + UInt32 t = group - 1; + Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); + } + #else + SetGroupSize(temp + prevGroupStart, j - prevGroupStart); + prevGroupStart = j; + #endif + } + else + thereAreGroups = 1; + { + UInt32 ind = ind2[val & mask]; + temp[j] = ind; + Groups[ind] = group; + } + } + + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + SetGroupSize(temp + prevGroupStart, j - prevGroupStart); + #endif + } + + for (j = 0; j < groupSize; j++) + ind2[j] = temp[j]; + return thereAreGroups; + } + + /* Check that all strings are in one group (cannot sort) */ + { + UInt32 group, j; + UInt32 sp = ind2[0] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; + group = Groups[sp]; + for (j = 1; j < groupSize; j++) + { + sp = ind2[j] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; + if (Groups[sp] != group) + break; + } + if (j == groupSize) + { + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + SetGroupSize(ind2, groupSize); + #endif + return 1; + } + } + + #ifndef BLOCK_SORT_USE_HEAP_SORT + { + /* ---------- Range Sort ---------- */ + UInt32 i; + UInt32 mid; + for (;;) + { + UInt32 j; + if (range <= 1) + { + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + SetGroupSize(ind2, groupSize); + #endif + return 1; + } + mid = left + ((range + 1) >> 1); + j = groupSize; + i = 0; + do + { + UInt32 sp = ind2[i] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; + if (Groups[sp] >= mid) + { + for (j--; j > i; j--) + { + sp = ind2[j] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; + if (Groups[sp] < mid) + { + UInt32 temp = ind2[i]; ind2[i] = ind2[j]; ind2[j] = temp; + break; + } + } + if (i >= j) + break; + } + } + while(++i < j); + if (i == 0) + { + range = range - (mid - left); + left = mid; + } + else if (i == groupSize) + range = (mid - left); + else + break; + } + + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + { + UInt32 t = (groupOffset + i - 1); + UInt32 *Flags = Groups + BlockSize; + Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); + } + #endif + + { + UInt32 j; + for (j = i; j < groupSize; j++) + Groups[ind2[j]] = groupOffset + i; + } + + { + UInt32 res = SortGroup(BlockSize, NumSortedBytes, groupOffset, i, NumRefBits, Indices, left, mid - left); + return res | SortGroup(BlockSize, NumSortedBytes, groupOffset + i, groupSize - i, NumRefBits, Indices, mid, range - (mid - left)); + } + + } + + #else + + /* ---------- Heap Sort ---------- */ + + { + UInt32 j; + for (j = 0; j < groupSize; j++) + { + UInt32 sp = ind2[j] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; + ind2[j] = sp; + } + + HeapSortRef(ind2, Groups, groupSize); + + /* Write Flags */ + { + UInt32 sp = ind2[0]; + UInt32 group = Groups[sp]; + + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 *Flags = Groups + BlockSize; + #else + UInt32 prevGroupStart = 0; + #endif + + for (j = 1; j < groupSize; j++) + { + sp = ind2[j]; + if (Groups[sp] != group) + { + group = Groups[sp]; + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + { + UInt32 t = groupOffset + j - 1; + Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); + } + #else + SetGroupSize(ind2 + prevGroupStart, j - prevGroupStart); + prevGroupStart = j; + #endif + } + } + + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + SetGroupSize(ind2 + prevGroupStart, j - prevGroupStart); + #endif + } + { + /* Write new Groups values and Check that there are groups */ + UInt32 thereAreGroups = 0; + for (j = 0; j < groupSize; j++) + { + UInt32 group = groupOffset + j; + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 subGroupSize = ((ind2[j] & ~0xC0000000) >> kNumBitsMax); + if ((ind2[j] & 0x40000000) != 0) + subGroupSize += ((ind2[j + 1] >> kNumBitsMax) << kNumExtra0Bits); + subGroupSize++; + for (;;) + { + UInt32 original = ind2[j]; + UInt32 sp = original & kIndexMask; + if (sp < NumSortedBytes) sp += BlockSize; sp -= NumSortedBytes; + ind2[j] = sp | (original & ~kIndexMask); + Groups[sp] = group; + if (--subGroupSize == 0) + break; + j++; + thereAreGroups = 1; + } + #else + UInt32 *Flags = Groups + BlockSize; + for (;;) + { + UInt32 sp = ind2[j]; if (sp < NumSortedBytes) sp += BlockSize; sp -= NumSortedBytes; + ind2[j] = sp; + Groups[sp] = group; + if ((Flags[(groupOffset + j) >> kNumFlagsBits] & (1 << ((groupOffset + j) & kFlagsMask))) == 0) + break; + j++; + thereAreGroups = 1; + } + #endif + } + return thereAreGroups; + } + } + #endif +} + +/* conditions: blockSize > 0 */ +UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize) +{ + UInt32 *counters = Indices + blockSize; + UInt32 i; + UInt32 *Groups; + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 *Flags; + #endif + + /* Radix-Sort for 2 bytes */ + for (i = 0; i < kNumHashValues; i++) + counters[i] = 0; + for (i = 0; i < blockSize - 1; i++) + counters[((UInt32)data[i] << 8) | data[i + 1]]++; + counters[((UInt32)data[i] << 8) | data[0]]++; + + Groups = counters + BS_TEMP_SIZE; + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + Flags = Groups + blockSize; + { + UInt32 numWords = (blockSize + kFlagsMask) >> kNumFlagsBits; + for (i = 0; i < numWords; i++) + Flags[i] = kAllFlags; + } + #endif + + { + UInt32 sum = 0; + for (i = 0; i < kNumHashValues; i++) + { + UInt32 groupSize = counters[i]; + if (groupSize > 0) + { + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 t = sum + groupSize - 1; + Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); + #endif + sum += groupSize; + } + counters[i] = sum - groupSize; + } + + for (i = 0; i < blockSize - 1; i++) + Groups[i] = counters[((UInt32)data[i] << 8) | data[i + 1]]; + Groups[i] = counters[((UInt32)data[i] << 8) | data[0]]; + + for (i = 0; i < blockSize - 1; i++) + Indices[counters[((UInt32)data[i] << 8) | data[i + 1]]++] = i; + Indices[counters[((UInt32)data[i] << 8) | data[0]]++] = i; + + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + { + UInt32 prev = 0; + for (i = 0; i < kNumHashValues; i++) + { + UInt32 prevGroupSize = counters[i] - prev; + if (prevGroupSize == 0) + continue; + SetGroupSize(Indices + prev, prevGroupSize); + prev = counters[i]; + } + } + #endif + } + + { + int NumRefBits; + UInt32 NumSortedBytes; + for (NumRefBits = 0; ((blockSize - 1) >> NumRefBits) != 0; NumRefBits++); + NumRefBits = 32 - NumRefBits; + if (NumRefBits > kNumRefBitsMax) + NumRefBits = kNumRefBitsMax; + + for (NumSortedBytes = kNumHashBytes; ; NumSortedBytes <<= 1) + { + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 finishedGroupSize = 0; + #endif + UInt32 newLimit = 0; + for (i = 0; i < blockSize;) + { + UInt32 groupSize; + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + + if ((Flags[i >> kNumFlagsBits] & (1 << (i & kFlagsMask))) == 0) + { + i++; + continue; + } + for(groupSize = 1; + (Flags[(i + groupSize) >> kNumFlagsBits] & (1 << ((i + groupSize) & kFlagsMask))) != 0; + groupSize++); + + groupSize++; + + #else + + groupSize = ((Indices[i] & ~0xC0000000) >> kNumBitsMax); + { + Bool finishedGroup = ((Indices[i] & 0x80000000) == 0); + if ((Indices[i] & 0x40000000) != 0) + { + groupSize += ((Indices[i + 1] >> kNumBitsMax) << kNumExtra0Bits); + Indices[i + 1] &= kIndexMask; + } + Indices[i] &= kIndexMask; + groupSize++; + if (finishedGroup || groupSize == 1) + { + Indices[i - finishedGroupSize] &= kIndexMask; + if (finishedGroupSize > 1) + Indices[i - finishedGroupSize + 1] &= kIndexMask; + { + UInt32 newGroupSize = groupSize + finishedGroupSize; + SetFinishedGroupSize(Indices + i - finishedGroupSize, newGroupSize); + finishedGroupSize = newGroupSize; + } + i += groupSize; + continue; + } + finishedGroupSize = 0; + } + + #endif + + if (NumSortedBytes >= blockSize) + { + UInt32 j; + for (j = 0; j < groupSize; j++) + { + UInt32 t = (i + j); + /* Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); */ + Groups[Indices[t]] = t; + } + } + else + if (SortGroup(blockSize, NumSortedBytes, i, groupSize, NumRefBits, Indices + #ifndef BLOCK_SORT_USE_HEAP_SORT + , 0, blockSize + #endif + ) != 0) + newLimit = i + groupSize; + i += groupSize; + } + if (newLimit == 0) + break; + } + } + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + for (i = 0; i < blockSize;) + { + UInt32 groupSize = ((Indices[i] & ~0xC0000000) >> kNumBitsMax); + if ((Indices[i] & 0x40000000) != 0) + { + groupSize += ((Indices[i + 1] >> kNumBitsMax) << kNumExtra0Bits); + Indices[i + 1] &= kIndexMask; + } + Indices[i] &= kIndexMask; + groupSize++; + i += groupSize; + } + #endif + return Groups[0]; +} + diff --git a/C/BwtSort.h b/C/BwtSort.h new file mode 100755 index 00000000..f373213e --- /dev/null +++ b/C/BwtSort.h @@ -0,0 +1,24 @@ +/* BwtSort.h -- BWT block sorting +2008-03-26 +Igor Pavlov +Public domain */ + +#ifndef __BWTSORT_H +#define __BWTSORT_H + +#include "Types.h" + +/* use BLOCK_SORT_EXTERNAL_FLAGS if blockSize can be > 1M */ +/* #define BLOCK_SORT_EXTERNAL_FLAGS */ + +#ifdef BLOCK_SORT_EXTERNAL_FLAGS +#define BLOCK_SORT_EXTERNAL_SIZE(blockSize) ((((blockSize) + 31) >> 5)) +#else +#define BLOCK_SORT_EXTERNAL_SIZE(blockSize) 0 +#endif + +#define BLOCK_SORT_BUF_SIZE(blockSize) ((blockSize) * 2 + BLOCK_SORT_EXTERNAL_SIZE(blockSize) + (1 << 16)) + +UInt32 BlockSort(UInt32 *indices, const Byte *data, UInt32 blockSize); + +#endif diff --git a/C/Compress/Branch/BranchARM.c b/C/Compress/Branch/BranchARM.c deleted file mode 100755 index da7db261..00000000 --- a/C/Compress/Branch/BranchARM.c +++ /dev/null @@ -1,26 +0,0 @@ -/* BranchARM.c */ - -#include "BranchARM.h" - -UInt32 ARM_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding) -{ - UInt32 i; - for (i = 0; i + 4 <= size; i += 4) - { - if (data[i + 3] == 0xEB) - { - UInt32 dest; - UInt32 src = (data[i + 2] << 16) | (data[i + 1] << 8) | (data[i + 0]); - src <<= 2; - if (encoding) - dest = nowPos + i + 8 + src; - else - dest = src - (nowPos + i + 8); - dest >>= 2; - data[i + 2] = (Byte)(dest >> 16); - data[i + 1] = (Byte)(dest >> 8); - data[i + 0] = (Byte)dest; - } - } - return i; -} diff --git a/C/Compress/Branch/BranchARM.h b/C/Compress/Branch/BranchARM.h deleted file mode 100755 index 3b4d63e1..00000000 --- a/C/Compress/Branch/BranchARM.h +++ /dev/null @@ -1,10 +0,0 @@ -/* BranchARM.h */ - -#ifndef __BRANCH_ARM_H -#define __BRANCH_ARM_H - -#include "BranchTypes.h" - -UInt32 ARM_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding); - -#endif diff --git a/C/Compress/Branch/BranchARMThumb.c b/C/Compress/Branch/BranchARMThumb.c deleted file mode 100755 index fa30e439..00000000 --- a/C/Compress/Branch/BranchARMThumb.c +++ /dev/null @@ -1,35 +0,0 @@ -/* BranchARMThumb.c */ - -#include "BranchARMThumb.h" - -UInt32 ARMThumb_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding) -{ - UInt32 i; - for (i = 0; i + 4 <= size; i += 2) - { - if ((data[i + 1] & 0xF8) == 0xF0 && - (data[i + 3] & 0xF8) == 0xF8) - { - UInt32 dest; - UInt32 src = - ((data[i + 1] & 0x7) << 19) | - (data[i + 0] << 11) | - ((data[i + 3] & 0x7) << 8) | - (data[i + 2]); - - src <<= 1; - if (encoding) - dest = nowPos + i + 4 + src; - else - dest = src - (nowPos + i + 4); - dest >>= 1; - - data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7)); - data[i + 0] = (Byte)(dest >> 11); - data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7)); - data[i + 2] = (Byte)dest; - i += 2; - } - } - return i; -} diff --git a/C/Compress/Branch/BranchARMThumb.h b/C/Compress/Branch/BranchARMThumb.h deleted file mode 100755 index 304699ce..00000000 --- a/C/Compress/Branch/BranchARMThumb.h +++ /dev/null @@ -1,10 +0,0 @@ -/* BranchARMThumb.h */ - -#ifndef __BRANCH_ARM_THUMB_H -#define __BRANCH_ARM_THUMB_H - -#include "BranchTypes.h" - -UInt32 ARMThumb_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding); - -#endif diff --git a/C/Compress/Branch/BranchIA64.h b/C/Compress/Branch/BranchIA64.h deleted file mode 100755 index 8213cb50..00000000 --- a/C/Compress/Branch/BranchIA64.h +++ /dev/null @@ -1,10 +0,0 @@ -/* BranchIA64.h */ - -#ifndef __BRANCH_IA64_H -#define __BRANCH_IA64_H - -#include "BranchTypes.h" - -UInt32 IA64_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding); - -#endif diff --git a/C/Compress/Branch/BranchPPC.c b/C/Compress/Branch/BranchPPC.c deleted file mode 100755 index b3e5703f..00000000 --- a/C/Compress/Branch/BranchPPC.c +++ /dev/null @@ -1,36 +0,0 @@ -/* BranchPPC.c */ - -#include "BranchPPC.h" - -UInt32 PPC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding) -{ - UInt32 i; - for (i = 0; i + 4 <= size; i += 4) - { - /* PowerPC branch 6(48) 24(Offset) 1(Abs) 1(Link) */ - if ((data[i] >> 2) == 0x12 && - ( - (data[i + 3] & 3) == 1 - /* || (data[i+3] & 3) == 3 */ - ) - ) - { - UInt32 src = ((data[i + 0] & 3) << 24) | - (data[i + 1] << 16) | - (data[i + 2] << 8) | - (data[i + 3] & (~3)); - - UInt32 dest; - if (encoding) - dest = nowPos + i + src; - else - dest = src - (nowPos + i); - data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3)); - data[i + 1] = (Byte)(dest >> 16); - data[i + 2] = (Byte)(dest >> 8); - data[i + 3] &= 0x3; - data[i + 3] |= dest; - } - } - return i; -} diff --git a/C/Compress/Branch/BranchPPC.h b/C/Compress/Branch/BranchPPC.h deleted file mode 100755 index 05e2a377..00000000 --- a/C/Compress/Branch/BranchPPC.h +++ /dev/null @@ -1,10 +0,0 @@ -/* BranchPPC.h */ - -#ifndef __BRANCH_PPC_H -#define __BRANCH_PPC_H - -#include "BranchTypes.h" - -UInt32 PPC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding); - -#endif diff --git a/C/Compress/Branch/BranchSPARC.c b/C/Compress/Branch/BranchSPARC.c deleted file mode 100755 index 79da2ea7..00000000 --- a/C/Compress/Branch/BranchSPARC.c +++ /dev/null @@ -1,36 +0,0 @@ -/* BranchSPARC.c */ - -#include "BranchSPARC.h" - -UInt32 SPARC_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding) -{ - UInt32 i; - for (i = 0; i + 4 <= size; i += 4) - { - if (data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00 || - data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0) - { - UInt32 src = - ((UInt32)data[i + 0] << 24) | - ((UInt32)data[i + 1] << 16) | - ((UInt32)data[i + 2] << 8) | - ((UInt32)data[i + 3]); - UInt32 dest; - - src <<= 2; - if (encoding) - dest = nowPos + i + src; - else - dest = src - (nowPos + i); - dest >>= 2; - - dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000; - - data[i + 0] = (Byte)(dest >> 24); - data[i + 1] = (Byte)(dest >> 16); - data[i + 2] = (Byte)(dest >> 8); - data[i + 3] = (Byte)dest; - } - } - return i; -} diff --git a/C/Compress/Branch/BranchSPARC.h b/C/Compress/Branch/BranchSPARC.h deleted file mode 100755 index f3f83206..00000000 --- a/C/Compress/Branch/BranchSPARC.h +++ /dev/null @@ -1,10 +0,0 @@ -/* BranchSPARC.h */ - -#ifndef __BRANCH_SPARC_H -#define __BRANCH_SPARC_H - -#include "BranchTypes.h" - -UInt32 SPARC_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding); - -#endif diff --git a/C/Compress/Branch/BranchTypes.h b/C/Compress/Branch/BranchTypes.h deleted file mode 100755 index 1bed56a9..00000000 --- a/C/Compress/Branch/BranchTypes.h +++ /dev/null @@ -1,51 +0,0 @@ -/* BranchTypes.h */ - -#ifndef __BRANCHTYPES_H -#define __BRANCHTYPES_H - -#ifndef _7ZIP_BYTE_DEFINED -#define _7ZIP_BYTE_DEFINED -typedef unsigned char Byte; -#endif - -#ifndef _7ZIP_UINT16_DEFINED -#define _7ZIP_UINT16_DEFINED -typedef unsigned short UInt16; -#endif - -#ifndef _7ZIP_UINT32_DEFINED -#define _7ZIP_UINT32_DEFINED -#ifdef _LZMA_UINT32_IS_ULONG -typedef unsigned long UInt32; -#else -typedef unsigned int UInt32; -#endif -#endif - -#ifndef _7ZIP_UINT64_DEFINED -#define _7ZIP_UINT64_DEFINED -#ifdef _SZ_NO_INT_64 -typedef unsigned long UInt64; -#else -#if defined(_MSC_VER) || defined(__BORLANDC__) -typedef unsigned __int64 UInt64; -#else -typedef unsigned long long int UInt64; -#endif -#endif -#endif - -/* #define _LZMA_NO_SYSTEM_SIZE_T */ -/* You can use it, if you don't want <stddef.h> */ - -#ifndef _7ZIP_SIZET_DEFINED -#define _7ZIP_SIZET_DEFINED -#ifdef _LZMA_NO_SYSTEM_SIZE_T -typedef UInt32 SizeT; -#else -#include <stddef.h> -typedef size_t SizeT; -#endif -#endif - -#endif diff --git a/C/Compress/Branch/BranchX86.h b/C/Compress/Branch/BranchX86.h deleted file mode 100755 index 5dfd02a7..00000000 --- a/C/Compress/Branch/BranchX86.h +++ /dev/null @@ -1,12 +0,0 @@ -/* BranchX86.h */ - -#ifndef __BRANCHX86_H -#define __BRANCHX86_H - -#include "BranchTypes.h" - -#define x86_Convert_Init(state) { state = 0; } - -SizeT x86_Convert(Byte *buffer, SizeT endPos, UInt32 nowPos, UInt32 *state, int encoding); - -#endif diff --git a/C/Compress/Lzma/LzmaDecode.c b/C/Compress/Lzma/LzmaDecode.c deleted file mode 100755 index cb834537..00000000 --- a/C/Compress/Lzma/LzmaDecode.c +++ /dev/null @@ -1,584 +0,0 @@ -/* - LzmaDecode.c - LZMA Decoder (optimized for Speed version) - - LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) - http://www.7-zip.org/ - - LZMA SDK is licensed under two licenses: - 1) GNU Lesser General Public License (GNU LGPL) - 2) Common Public License (CPL) - It means that you can select one of these two licenses and - follow rules of that license. - - SPECIAL EXCEPTION: - Igor Pavlov, as the author of this Code, expressly permits you to - statically or dynamically link your Code (or bind by name) to the - interfaces of this file without subjecting your linked Code to the - terms of the CPL or GNU LGPL. Any modifications or additions - to this file, however, are subject to the LGPL or CPL terms. -*/ - -#include "LzmaDecode.h" - -#define kNumTopBits 24 -#define kTopValue ((UInt32)1 << kNumTopBits) - -#define kNumBitModelTotalBits 11 -#define kBitModelTotal (1 << kNumBitModelTotalBits) -#define kNumMoveBits 5 - -#define RC_READ_BYTE (*Buffer++) - -#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \ - { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }} - -#ifdef _LZMA_IN_CB - -#define RC_TEST { if (Buffer == BufferLim) \ - { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \ - BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }} - -#define RC_INIT Buffer = BufferLim = 0; RC_INIT2 - -#else - -#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; } - -#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2 - -#endif - -#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; } - -#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound) -#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits; -#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits; - -#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \ - { UpdateBit0(p); mi <<= 1; A0; } else \ - { UpdateBit1(p); mi = (mi + mi) + 1; A1; } - -#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;) - -#define RangeDecoderBitTreeDecode(probs, numLevels, res) \ - { int i = numLevels; res = 1; \ - do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \ - res -= (1 << numLevels); } - - -#define kNumPosBitsMax 4 -#define kNumPosStatesMax (1 << kNumPosBitsMax) - -#define kLenNumLowBits 3 -#define kLenNumLowSymbols (1 << kLenNumLowBits) -#define kLenNumMidBits 3 -#define kLenNumMidSymbols (1 << kLenNumMidBits) -#define kLenNumHighBits 8 -#define kLenNumHighSymbols (1 << kLenNumHighBits) - -#define LenChoice 0 -#define LenChoice2 (LenChoice + 1) -#define LenLow (LenChoice2 + 1) -#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) -#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) -#define kNumLenProbs (LenHigh + kLenNumHighSymbols) - - -#define kNumStates 12 -#define kNumLitStates 7 - -#define kStartPosModelIndex 4 -#define kEndPosModelIndex 14 -#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) - -#define kNumPosSlotBits 6 -#define kNumLenToPosStates 4 - -#define kNumAlignBits 4 -#define kAlignTableSize (1 << kNumAlignBits) - -#define kMatchMinLen 2 - -#define IsMatch 0 -#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) -#define IsRepG0 (IsRep + kNumStates) -#define IsRepG1 (IsRepG0 + kNumStates) -#define IsRepG2 (IsRepG1 + kNumStates) -#define IsRep0Long (IsRepG2 + kNumStates) -#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) -#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) -#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) -#define LenCoder (Align + kAlignTableSize) -#define RepLenCoder (LenCoder + kNumLenProbs) -#define Literal (RepLenCoder + kNumLenProbs) - -#if Literal != LZMA_BASE_SIZE -StopCompilingDueBUG -#endif - -int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size) -{ - unsigned char prop0; - if (size < LZMA_PROPERTIES_SIZE) - return LZMA_RESULT_DATA_ERROR; - prop0 = propsData[0]; - if (prop0 >= (9 * 5 * 5)) - return LZMA_RESULT_DATA_ERROR; - { - for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5)); - for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9); - propsRes->lc = prop0; - /* - unsigned char remainder = (unsigned char)(prop0 / 9); - propsRes->lc = prop0 % 9; - propsRes->pb = remainder / 5; - propsRes->lp = remainder % 5; - */ - } - - #ifdef _LZMA_OUT_READ - { - int i; - propsRes->DictionarySize = 0; - for (i = 0; i < 4; i++) - propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8); - if (propsRes->DictionarySize == 0) - propsRes->DictionarySize = 1; - } - #endif - return LZMA_RESULT_OK; -} - -#define kLzmaStreamWasFinishedId (-1) - -int LzmaDecode(CLzmaDecoderState *vs, - #ifdef _LZMA_IN_CB - ILzmaInCallback *InCallback, - #else - const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, - #endif - unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed) -{ - CProb *p = vs->Probs; - SizeT nowPos = 0; - Byte previousByte = 0; - UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1; - UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1; - int lc = vs->Properties.lc; - - #ifdef _LZMA_OUT_READ - - UInt32 Range = vs->Range; - UInt32 Code = vs->Code; - #ifdef _LZMA_IN_CB - const Byte *Buffer = vs->Buffer; - const Byte *BufferLim = vs->BufferLim; - #else - const Byte *Buffer = inStream; - const Byte *BufferLim = inStream + inSize; - #endif - int state = vs->State; - UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; - int len = vs->RemainLen; - UInt32 globalPos = vs->GlobalPos; - UInt32 distanceLimit = vs->DistanceLimit; - - Byte *dictionary = vs->Dictionary; - UInt32 dictionarySize = vs->Properties.DictionarySize; - UInt32 dictionaryPos = vs->DictionaryPos; - - Byte tempDictionary[4]; - - #ifndef _LZMA_IN_CB - *inSizeProcessed = 0; - #endif - *outSizeProcessed = 0; - if (len == kLzmaStreamWasFinishedId) - return LZMA_RESULT_OK; - - if (dictionarySize == 0) - { - dictionary = tempDictionary; - dictionarySize = 1; - tempDictionary[0] = vs->TempDictionary[0]; - } - - if (len == kLzmaNeedInitId) - { - { - UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); - UInt32 i; - for (i = 0; i < numProbs; i++) - p[i] = kBitModelTotal >> 1; - rep0 = rep1 = rep2 = rep3 = 1; - state = 0; - globalPos = 0; - distanceLimit = 0; - dictionaryPos = 0; - dictionary[dictionarySize - 1] = 0; - #ifdef _LZMA_IN_CB - RC_INIT; - #else - RC_INIT(inStream, inSize); - #endif - } - len = 0; - } - while(len != 0 && nowPos < outSize) - { - UInt32 pos = dictionaryPos - rep0; - if (pos >= dictionarySize) - pos += dictionarySize; - outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos]; - if (++dictionaryPos == dictionarySize) - dictionaryPos = 0; - len--; - } - if (dictionaryPos == 0) - previousByte = dictionary[dictionarySize - 1]; - else - previousByte = dictionary[dictionaryPos - 1]; - - #else /* if !_LZMA_OUT_READ */ - - int state = 0; - UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; - int len = 0; - const Byte *Buffer; - const Byte *BufferLim; - UInt32 Range; - UInt32 Code; - - #ifndef _LZMA_IN_CB - *inSizeProcessed = 0; - #endif - *outSizeProcessed = 0; - - { - UInt32 i; - UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); - for (i = 0; i < numProbs; i++) - p[i] = kBitModelTotal >> 1; - } - - #ifdef _LZMA_IN_CB - RC_INIT; - #else - RC_INIT(inStream, inSize); - #endif - - #endif /* _LZMA_OUT_READ */ - - while(nowPos < outSize) - { - CProb *prob; - UInt32 bound; - int posState = (int)( - (nowPos - #ifdef _LZMA_OUT_READ - + globalPos - #endif - ) - & posStateMask); - - prob = p + IsMatch + (state << kNumPosBitsMax) + posState; - IfBit0(prob) - { - int symbol = 1; - UpdateBit0(prob) - prob = p + Literal + (LZMA_LIT_SIZE * - ((( - (nowPos - #ifdef _LZMA_OUT_READ - + globalPos - #endif - ) - & literalPosMask) << lc) + (previousByte >> (8 - lc)))); - - if (state >= kNumLitStates) - { - int matchByte; - #ifdef _LZMA_OUT_READ - UInt32 pos = dictionaryPos - rep0; - if (pos >= dictionarySize) - pos += dictionarySize; - matchByte = dictionary[pos]; - #else - matchByte = outStream[nowPos - rep0]; - #endif - do - { - int bit; - CProb *probLit; - matchByte <<= 1; - bit = (matchByte & 0x100); - probLit = prob + 0x100 + bit + symbol; - RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break) - } - while (symbol < 0x100); - } - while (symbol < 0x100) - { - CProb *probLit = prob + symbol; - RC_GET_BIT(probLit, symbol) - } - previousByte = (Byte)symbol; - - outStream[nowPos++] = previousByte; - #ifdef _LZMA_OUT_READ - if (distanceLimit < dictionarySize) - distanceLimit++; - - dictionary[dictionaryPos] = previousByte; - if (++dictionaryPos == dictionarySize) - dictionaryPos = 0; - #endif - if (state < 4) state = 0; - else if (state < 10) state -= 3; - else state -= 6; - } - else - { - UpdateBit1(prob); - prob = p + IsRep + state; - IfBit0(prob) - { - UpdateBit0(prob); - rep3 = rep2; - rep2 = rep1; - rep1 = rep0; - state = state < kNumLitStates ? 0 : 3; - prob = p + LenCoder; - } - else - { - UpdateBit1(prob); - prob = p + IsRepG0 + state; - IfBit0(prob) - { - UpdateBit0(prob); - prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState; - IfBit0(prob) - { - #ifdef _LZMA_OUT_READ - UInt32 pos; - #endif - UpdateBit0(prob); - - #ifdef _LZMA_OUT_READ - if (distanceLimit == 0) - #else - if (nowPos == 0) - #endif - return LZMA_RESULT_DATA_ERROR; - - state = state < kNumLitStates ? 9 : 11; - #ifdef _LZMA_OUT_READ - pos = dictionaryPos - rep0; - if (pos >= dictionarySize) - pos += dictionarySize; - previousByte = dictionary[pos]; - dictionary[dictionaryPos] = previousByte; - if (++dictionaryPos == dictionarySize) - dictionaryPos = 0; - #else - previousByte = outStream[nowPos - rep0]; - #endif - outStream[nowPos++] = previousByte; - #ifdef _LZMA_OUT_READ - if (distanceLimit < dictionarySize) - distanceLimit++; - #endif - - continue; - } - else - { - UpdateBit1(prob); - } - } - else - { - UInt32 distance; - UpdateBit1(prob); - prob = p + IsRepG1 + state; - IfBit0(prob) - { - UpdateBit0(prob); - distance = rep1; - } - else - { - UpdateBit1(prob); - prob = p + IsRepG2 + state; - IfBit0(prob) - { - UpdateBit0(prob); - distance = rep2; - } - else - { - UpdateBit1(prob); - distance = rep3; - rep3 = rep2; - } - rep2 = rep1; - } - rep1 = rep0; - rep0 = distance; - } - state = state < kNumLitStates ? 8 : 11; - prob = p + RepLenCoder; - } - { - int numBits, offset; - CProb *probLen = prob + LenChoice; - IfBit0(probLen) - { - UpdateBit0(probLen); - probLen = prob + LenLow + (posState << kLenNumLowBits); - offset = 0; - numBits = kLenNumLowBits; - } - else - { - UpdateBit1(probLen); - probLen = prob + LenChoice2; - IfBit0(probLen) - { - UpdateBit0(probLen); - probLen = prob + LenMid + (posState << kLenNumMidBits); - offset = kLenNumLowSymbols; - numBits = kLenNumMidBits; - } - else - { - UpdateBit1(probLen); - probLen = prob + LenHigh; - offset = kLenNumLowSymbols + kLenNumMidSymbols; - numBits = kLenNumHighBits; - } - } - RangeDecoderBitTreeDecode(probLen, numBits, len); - len += offset; - } - - if (state < 4) - { - int posSlot; - state += kNumLitStates; - prob = p + PosSlot + - ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << - kNumPosSlotBits); - RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot); - if (posSlot >= kStartPosModelIndex) - { - int numDirectBits = ((posSlot >> 1) - 1); - rep0 = (2 | ((UInt32)posSlot & 1)); - if (posSlot < kEndPosModelIndex) - { - rep0 <<= numDirectBits; - prob = p + SpecPos + rep0 - posSlot - 1; - } - else - { - numDirectBits -= kNumAlignBits; - do - { - RC_NORMALIZE - Range >>= 1; - rep0 <<= 1; - if (Code >= Range) - { - Code -= Range; - rep0 |= 1; - } - } - while (--numDirectBits != 0); - prob = p + Align; - rep0 <<= kNumAlignBits; - numDirectBits = kNumAlignBits; - } - { - int i = 1; - int mi = 1; - do - { - CProb *prob3 = prob + mi; - RC_GET_BIT2(prob3, mi, ; , rep0 |= i); - i <<= 1; - } - while(--numDirectBits != 0); - } - } - else - rep0 = posSlot; - if (++rep0 == (UInt32)(0)) - { - /* it's for stream version */ - len = kLzmaStreamWasFinishedId; - break; - } - } - - len += kMatchMinLen; - #ifdef _LZMA_OUT_READ - if (rep0 > distanceLimit) - #else - if (rep0 > nowPos) - #endif - return LZMA_RESULT_DATA_ERROR; - - #ifdef _LZMA_OUT_READ - if (dictionarySize - distanceLimit > (UInt32)len) - distanceLimit += len; - else - distanceLimit = dictionarySize; - #endif - - do - { - #ifdef _LZMA_OUT_READ - UInt32 pos = dictionaryPos - rep0; - if (pos >= dictionarySize) - pos += dictionarySize; - previousByte = dictionary[pos]; - dictionary[dictionaryPos] = previousByte; - if (++dictionaryPos == dictionarySize) - dictionaryPos = 0; - #else - previousByte = outStream[nowPos - rep0]; - #endif - len--; - outStream[nowPos++] = previousByte; - } - while(len != 0 && nowPos < outSize); - } - } - RC_NORMALIZE; - - #ifdef _LZMA_OUT_READ - vs->Range = Range; - vs->Code = Code; - vs->DictionaryPos = dictionaryPos; - vs->GlobalPos = globalPos + (UInt32)nowPos; - vs->DistanceLimit = distanceLimit; - vs->Reps[0] = rep0; - vs->Reps[1] = rep1; - vs->Reps[2] = rep2; - vs->Reps[3] = rep3; - vs->State = state; - vs->RemainLen = len; - vs->TempDictionary[0] = tempDictionary[0]; - #endif - - #ifdef _LZMA_IN_CB - vs->Buffer = Buffer; - vs->BufferLim = BufferLim; - #else - *inSizeProcessed = (SizeT)(Buffer - inStream); - #endif - *outSizeProcessed = nowPos; - return LZMA_RESULT_OK; -} diff --git a/C/Compress/Lzma/LzmaDecode.h b/C/Compress/Lzma/LzmaDecode.h deleted file mode 100755 index 2870eeb9..00000000 --- a/C/Compress/Lzma/LzmaDecode.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - LzmaDecode.h - LZMA Decoder interface - - LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) - http://www.7-zip.org/ - - LZMA SDK is licensed under two licenses: - 1) GNU Lesser General Public License (GNU LGPL) - 2) Common Public License (CPL) - It means that you can select one of these two licenses and - follow rules of that license. - - SPECIAL EXCEPTION: - Igor Pavlov, as the author of this code, expressly permits you to - statically or dynamically link your code (or bind by name) to the - interfaces of this file without subjecting your linked code to the - terms of the CPL or GNU LGPL. Any modifications or additions - to this file, however, are subject to the LGPL or CPL terms. -*/ - -#ifndef __LZMADECODE_H -#define __LZMADECODE_H - -#include "LzmaTypes.h" - -/* #define _LZMA_IN_CB */ -/* Use callback for input data */ - -/* #define _LZMA_OUT_READ */ -/* Use read function for output data */ - -/* #define _LZMA_PROB32 */ -/* It can increase speed on some 32-bit CPUs, - but memory usage will be doubled in that case */ - -/* #define _LZMA_LOC_OPT */ -/* Enable local speed optimizations inside code */ - -#ifdef _LZMA_PROB32 -#define CProb UInt32 -#else -#define CProb UInt16 -#endif - -#define LZMA_RESULT_OK 0 -#define LZMA_RESULT_DATA_ERROR 1 - -#ifdef _LZMA_IN_CB -typedef struct _ILzmaInCallback -{ - int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize); -} ILzmaInCallback; -#endif - -#define LZMA_BASE_SIZE 1846 -#define LZMA_LIT_SIZE 768 - -#define LZMA_PROPERTIES_SIZE 5 - -typedef struct _CLzmaProperties -{ - int lc; - int lp; - int pb; - #ifdef _LZMA_OUT_READ - UInt32 DictionarySize; - #endif -}CLzmaProperties; - -int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size); - -#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp))) - -#define kLzmaNeedInitId (-2) - -typedef struct _CLzmaDecoderState -{ - CLzmaProperties Properties; - CProb *Probs; - - #ifdef _LZMA_IN_CB - const unsigned char *Buffer; - const unsigned char *BufferLim; - #endif - - #ifdef _LZMA_OUT_READ - unsigned char *Dictionary; - UInt32 Range; - UInt32 Code; - UInt32 DictionaryPos; - UInt32 GlobalPos; - UInt32 DistanceLimit; - UInt32 Reps[4]; - int State; - int RemainLen; - unsigned char TempDictionary[4]; - #endif -} CLzmaDecoderState; - -#ifdef _LZMA_OUT_READ -#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; } -#endif - -int LzmaDecode(CLzmaDecoderState *vs, - #ifdef _LZMA_IN_CB - ILzmaInCallback *inCallback, - #else - const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, - #endif - unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed); - -#endif diff --git a/C/Compress/Lzma/LzmaDecodeSize.c b/C/Compress/Lzma/LzmaDecodeSize.c deleted file mode 100755 index a3a5eb9d..00000000 --- a/C/Compress/Lzma/LzmaDecodeSize.c +++ /dev/null @@ -1,712 +0,0 @@ -/* - LzmaDecodeSize.c - LZMA Decoder (optimized for Size version) - - LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) - http://www.7-zip.org/ - - LZMA SDK is licensed under two licenses: - 1) GNU Lesser General Public License (GNU LGPL) - 2) Common Public License (CPL) - It means that you can select one of these two licenses and - follow rules of that license. - - SPECIAL EXCEPTION: - Igor Pavlov, as the author of this code, expressly permits you to - statically or dynamically link your code (or bind by name) to the - interfaces of this file without subjecting your linked code to the - terms of the CPL or GNU LGPL. Any modifications or additions - to this file, however, are subject to the LGPL or CPL terms. -*/ - -#include "LzmaDecode.h" - -#define kNumTopBits 24 -#define kTopValue ((UInt32)1 << kNumTopBits) - -#define kNumBitModelTotalBits 11 -#define kBitModelTotal (1 << kNumBitModelTotalBits) -#define kNumMoveBits 5 - -typedef struct _CRangeDecoder -{ - const Byte *Buffer; - const Byte *BufferLim; - UInt32 Range; - UInt32 Code; - #ifdef _LZMA_IN_CB - ILzmaInCallback *InCallback; - int Result; - #endif - int ExtraBytes; -} CRangeDecoder; - -Byte RangeDecoderReadByte(CRangeDecoder *rd) -{ - if (rd->Buffer == rd->BufferLim) - { - #ifdef _LZMA_IN_CB - SizeT size; - rd->Result = rd->InCallback->Read(rd->InCallback, &rd->Buffer, &size); - rd->BufferLim = rd->Buffer + size; - if (size == 0) - #endif - { - rd->ExtraBytes = 1; - return 0xFF; - } - } - return (*rd->Buffer++); -} - -/* #define ReadByte (*rd->Buffer++) */ -#define ReadByte (RangeDecoderReadByte(rd)) - -void RangeDecoderInit(CRangeDecoder *rd - #ifndef _LZMA_IN_CB - , const Byte *stream, SizeT bufferSize - #endif - ) -{ - int i; - #ifdef _LZMA_IN_CB - rd->Buffer = rd->BufferLim = 0; - #else - rd->Buffer = stream; - rd->BufferLim = stream + bufferSize; - #endif - rd->ExtraBytes = 0; - rd->Code = 0; - rd->Range = (0xFFFFFFFF); - for(i = 0; i < 5; i++) - rd->Code = (rd->Code << 8) | ReadByte; -} - -#define RC_INIT_VAR UInt32 range = rd->Range; UInt32 code = rd->Code; -#define RC_FLUSH_VAR rd->Range = range; rd->Code = code; -#define RC_NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | ReadByte; } - -UInt32 RangeDecoderDecodeDirectBits(CRangeDecoder *rd, int numTotalBits) -{ - RC_INIT_VAR - UInt32 result = 0; - int i; - for (i = numTotalBits; i != 0; i--) - { - /* UInt32 t; */ - range >>= 1; - - result <<= 1; - if (code >= range) - { - code -= range; - result |= 1; - } - /* - t = (code - range) >> 31; - t &= 1; - code -= range & (t - 1); - result = (result + result) | (1 - t); - */ - RC_NORMALIZE - } - RC_FLUSH_VAR - return result; -} - -int RangeDecoderBitDecode(CProb *prob, CRangeDecoder *rd) -{ - UInt32 bound = (rd->Range >> kNumBitModelTotalBits) * *prob; - if (rd->Code < bound) - { - rd->Range = bound; - *prob += (kBitModelTotal - *prob) >> kNumMoveBits; - if (rd->Range < kTopValue) - { - rd->Code = (rd->Code << 8) | ReadByte; - rd->Range <<= 8; - } - return 0; - } - else - { - rd->Range -= bound; - rd->Code -= bound; - *prob -= (*prob) >> kNumMoveBits; - if (rd->Range < kTopValue) - { - rd->Code = (rd->Code << 8) | ReadByte; - rd->Range <<= 8; - } - return 1; - } -} - -#define RC_GET_BIT2(prob, mi, A0, A1) \ - UInt32 bound = (range >> kNumBitModelTotalBits) * *prob; \ - if (code < bound) \ - { A0; range = bound; *prob += (kBitModelTotal - *prob) >> kNumMoveBits; mi <<= 1; } \ - else \ - { A1; range -= bound; code -= bound; *prob -= (*prob) >> kNumMoveBits; mi = (mi + mi) + 1; } \ - RC_NORMALIZE - -#define RC_GET_BIT(prob, mi) RC_GET_BIT2(prob, mi, ; , ;) - -int RangeDecoderBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd) -{ - int mi = 1; - int i; - #ifdef _LZMA_LOC_OPT - RC_INIT_VAR - #endif - for(i = numLevels; i != 0; i--) - { - #ifdef _LZMA_LOC_OPT - CProb *prob = probs + mi; - RC_GET_BIT(prob, mi) - #else - mi = (mi + mi) + RangeDecoderBitDecode(probs + mi, rd); - #endif - } - #ifdef _LZMA_LOC_OPT - RC_FLUSH_VAR - #endif - return mi - (1 << numLevels); -} - -int RangeDecoderReverseBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd) -{ - int mi = 1; - int i; - int symbol = 0; - #ifdef _LZMA_LOC_OPT - RC_INIT_VAR - #endif - for(i = 0; i < numLevels; i++) - { - #ifdef _LZMA_LOC_OPT - CProb *prob = probs + mi; - RC_GET_BIT2(prob, mi, ; , symbol |= (1 << i)) - #else - int bit = RangeDecoderBitDecode(probs + mi, rd); - mi = mi + mi + bit; - symbol |= (bit << i); - #endif - } - #ifdef _LZMA_LOC_OPT - RC_FLUSH_VAR - #endif - return symbol; -} - -Byte LzmaLiteralDecode(CProb *probs, CRangeDecoder *rd) -{ - int symbol = 1; - #ifdef _LZMA_LOC_OPT - RC_INIT_VAR - #endif - do - { - #ifdef _LZMA_LOC_OPT - CProb *prob = probs + symbol; - RC_GET_BIT(prob, symbol) - #else - symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd); - #endif - } - while (symbol < 0x100); - #ifdef _LZMA_LOC_OPT - RC_FLUSH_VAR - #endif - return symbol; -} - -Byte LzmaLiteralDecodeMatch(CProb *probs, CRangeDecoder *rd, Byte matchByte) -{ - int symbol = 1; - #ifdef _LZMA_LOC_OPT - RC_INIT_VAR - #endif - do - { - int bit; - int matchBit = (matchByte >> 7) & 1; - matchByte <<= 1; - #ifdef _LZMA_LOC_OPT - { - CProb *prob = probs + 0x100 + (matchBit << 8) + symbol; - RC_GET_BIT2(prob, symbol, bit = 0, bit = 1) - } - #else - bit = RangeDecoderBitDecode(probs + 0x100 + (matchBit << 8) + symbol, rd); - symbol = (symbol << 1) | bit; - #endif - if (matchBit != bit) - { - while (symbol < 0x100) - { - #ifdef _LZMA_LOC_OPT - CProb *prob = probs + symbol; - RC_GET_BIT(prob, symbol) - #else - symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd); - #endif - } - break; - } - } - while (symbol < 0x100); - #ifdef _LZMA_LOC_OPT - RC_FLUSH_VAR - #endif - return symbol; -} - -#define kNumPosBitsMax 4 -#define kNumPosStatesMax (1 << kNumPosBitsMax) - -#define kLenNumLowBits 3 -#define kLenNumLowSymbols (1 << kLenNumLowBits) -#define kLenNumMidBits 3 -#define kLenNumMidSymbols (1 << kLenNumMidBits) -#define kLenNumHighBits 8 -#define kLenNumHighSymbols (1 << kLenNumHighBits) - -#define LenChoice 0 -#define LenChoice2 (LenChoice + 1) -#define LenLow (LenChoice2 + 1) -#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) -#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) -#define kNumLenProbs (LenHigh + kLenNumHighSymbols) - -int LzmaLenDecode(CProb *p, CRangeDecoder *rd, int posState) -{ - if(RangeDecoderBitDecode(p + LenChoice, rd) == 0) - return RangeDecoderBitTreeDecode(p + LenLow + - (posState << kLenNumLowBits), kLenNumLowBits, rd); - if(RangeDecoderBitDecode(p + LenChoice2, rd) == 0) - return kLenNumLowSymbols + RangeDecoderBitTreeDecode(p + LenMid + - (posState << kLenNumMidBits), kLenNumMidBits, rd); - return kLenNumLowSymbols + kLenNumMidSymbols + - RangeDecoderBitTreeDecode(p + LenHigh, kLenNumHighBits, rd); -} - -#define kNumStates 12 -#define kNumLitStates 7 - -#define kStartPosModelIndex 4 -#define kEndPosModelIndex 14 -#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) - -#define kNumPosSlotBits 6 -#define kNumLenToPosStates 4 - -#define kNumAlignBits 4 -#define kAlignTableSize (1 << kNumAlignBits) - -#define kMatchMinLen 2 - -#define IsMatch 0 -#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) -#define IsRepG0 (IsRep + kNumStates) -#define IsRepG1 (IsRepG0 + kNumStates) -#define IsRepG2 (IsRepG1 + kNumStates) -#define IsRep0Long (IsRepG2 + kNumStates) -#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) -#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) -#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) -#define LenCoder (Align + kAlignTableSize) -#define RepLenCoder (LenCoder + kNumLenProbs) -#define Literal (RepLenCoder + kNumLenProbs) - -#if Literal != LZMA_BASE_SIZE -StopCompilingDueBUG -#endif - -int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size) -{ - unsigned char prop0; - if (size < LZMA_PROPERTIES_SIZE) - return LZMA_RESULT_DATA_ERROR; - prop0 = propsData[0]; - if (prop0 >= (9 * 5 * 5)) - return LZMA_RESULT_DATA_ERROR; - { - for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5)); - for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9); - propsRes->lc = prop0; - /* - unsigned char remainder = (unsigned char)(prop0 / 9); - propsRes->lc = prop0 % 9; - propsRes->pb = remainder / 5; - propsRes->lp = remainder % 5; - */ - } - - #ifdef _LZMA_OUT_READ - { - int i; - propsRes->DictionarySize = 0; - for (i = 0; i < 4; i++) - propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8); - if (propsRes->DictionarySize == 0) - propsRes->DictionarySize = 1; - } - #endif - return LZMA_RESULT_OK; -} - -#define kLzmaStreamWasFinishedId (-1) - -int LzmaDecode(CLzmaDecoderState *vs, - #ifdef _LZMA_IN_CB - ILzmaInCallback *InCallback, - #else - const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, - #endif - unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed) -{ - CProb *p = vs->Probs; - SizeT nowPos = 0; - Byte previousByte = 0; - UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1; - UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1; - int lc = vs->Properties.lc; - CRangeDecoder rd; - - #ifdef _LZMA_OUT_READ - - int state = vs->State; - UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; - int len = vs->RemainLen; - UInt32 globalPos = vs->GlobalPos; - UInt32 distanceLimit = vs->DistanceLimit; - - Byte *dictionary = vs->Dictionary; - UInt32 dictionarySize = vs->Properties.DictionarySize; - UInt32 dictionaryPos = vs->DictionaryPos; - - Byte tempDictionary[4]; - - rd.Range = vs->Range; - rd.Code = vs->Code; - #ifdef _LZMA_IN_CB - rd.InCallback = InCallback; - rd.Buffer = vs->Buffer; - rd.BufferLim = vs->BufferLim; - #else - rd.Buffer = inStream; - rd.BufferLim = inStream + inSize; - #endif - - #ifndef _LZMA_IN_CB - *inSizeProcessed = 0; - #endif - *outSizeProcessed = 0; - if (len == kLzmaStreamWasFinishedId) - return LZMA_RESULT_OK; - - if (dictionarySize == 0) - { - dictionary = tempDictionary; - dictionarySize = 1; - tempDictionary[0] = vs->TempDictionary[0]; - } - - if (len == kLzmaNeedInitId) - { - { - UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); - UInt32 i; - for (i = 0; i < numProbs; i++) - p[i] = kBitModelTotal >> 1; - rep0 = rep1 = rep2 = rep3 = 1; - state = 0; - globalPos = 0; - distanceLimit = 0; - dictionaryPos = 0; - dictionary[dictionarySize - 1] = 0; - RangeDecoderInit(&rd - #ifndef _LZMA_IN_CB - , inStream, inSize - #endif - ); - #ifdef _LZMA_IN_CB - if (rd.Result != LZMA_RESULT_OK) - return rd.Result; - #endif - if (rd.ExtraBytes != 0) - return LZMA_RESULT_DATA_ERROR; - } - len = 0; - } - while(len != 0 && nowPos < outSize) - { - UInt32 pos = dictionaryPos - rep0; - if (pos >= dictionarySize) - pos += dictionarySize; - outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos]; - if (++dictionaryPos == dictionarySize) - dictionaryPos = 0; - len--; - } - if (dictionaryPos == 0) - previousByte = dictionary[dictionarySize - 1]; - else - previousByte = dictionary[dictionaryPos - 1]; - - #ifdef _LZMA_IN_CB - rd.Result = LZMA_RESULT_OK; - #endif - rd.ExtraBytes = 0; - - #else /* if !_LZMA_OUT_READ */ - - int state = 0; - UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; - int len = 0; - - #ifndef _LZMA_IN_CB - *inSizeProcessed = 0; - #endif - *outSizeProcessed = 0; - - { - UInt32 i; - UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); - for (i = 0; i < numProbs; i++) - p[i] = kBitModelTotal >> 1; - } - - #ifdef _LZMA_IN_CB - rd.InCallback = InCallback; - #endif - RangeDecoderInit(&rd - #ifndef _LZMA_IN_CB - , inStream, inSize - #endif - ); - - #ifdef _LZMA_IN_CB - if (rd.Result != LZMA_RESULT_OK) - return rd.Result; - #endif - if (rd.ExtraBytes != 0) - return LZMA_RESULT_DATA_ERROR; - - #endif /* _LZMA_OUT_READ */ - - - while(nowPos < outSize) - { - int posState = (int)( - (nowPos - #ifdef _LZMA_OUT_READ - + globalPos - #endif - ) - & posStateMask); - #ifdef _LZMA_IN_CB - if (rd.Result != LZMA_RESULT_OK) - return rd.Result; - #endif - if (rd.ExtraBytes != 0) - return LZMA_RESULT_DATA_ERROR; - if (RangeDecoderBitDecode(p + IsMatch + (state << kNumPosBitsMax) + posState, &rd) == 0) - { - CProb *probs = p + Literal + (LZMA_LIT_SIZE * - ((( - (nowPos - #ifdef _LZMA_OUT_READ - + globalPos - #endif - ) - & literalPosMask) << lc) + (previousByte >> (8 - lc)))); - - if (state >= kNumLitStates) - { - Byte matchByte; - #ifdef _LZMA_OUT_READ - UInt32 pos = dictionaryPos - rep0; - if (pos >= dictionarySize) - pos += dictionarySize; - matchByte = dictionary[pos]; - #else - matchByte = outStream[nowPos - rep0]; - #endif - previousByte = LzmaLiteralDecodeMatch(probs, &rd, matchByte); - } - else - previousByte = LzmaLiteralDecode(probs, &rd); - outStream[nowPos++] = previousByte; - #ifdef _LZMA_OUT_READ - if (distanceLimit < dictionarySize) - distanceLimit++; - - dictionary[dictionaryPos] = previousByte; - if (++dictionaryPos == dictionarySize) - dictionaryPos = 0; - #endif - if (state < 4) state = 0; - else if (state < 10) state -= 3; - else state -= 6; - } - else - { - if (RangeDecoderBitDecode(p + IsRep + state, &rd) == 1) - { - if (RangeDecoderBitDecode(p + IsRepG0 + state, &rd) == 0) - { - if (RangeDecoderBitDecode(p + IsRep0Long + (state << kNumPosBitsMax) + posState, &rd) == 0) - { - #ifdef _LZMA_OUT_READ - UInt32 pos; - #endif - - #ifdef _LZMA_OUT_READ - if (distanceLimit == 0) - #else - if (nowPos == 0) - #endif - return LZMA_RESULT_DATA_ERROR; - - state = state < 7 ? 9 : 11; - #ifdef _LZMA_OUT_READ - pos = dictionaryPos - rep0; - if (pos >= dictionarySize) - pos += dictionarySize; - previousByte = dictionary[pos]; - dictionary[dictionaryPos] = previousByte; - if (++dictionaryPos == dictionarySize) - dictionaryPos = 0; - #else - previousByte = outStream[nowPos - rep0]; - #endif - outStream[nowPos++] = previousByte; - - #ifdef _LZMA_OUT_READ - if (distanceLimit < dictionarySize) - distanceLimit++; - #endif - continue; - } - } - else - { - UInt32 distance; - if(RangeDecoderBitDecode(p + IsRepG1 + state, &rd) == 0) - distance = rep1; - else - { - if(RangeDecoderBitDecode(p + IsRepG2 + state, &rd) == 0) - distance = rep2; - else - { - distance = rep3; - rep3 = rep2; - } - rep2 = rep1; - } - rep1 = rep0; - rep0 = distance; - } - len = LzmaLenDecode(p + RepLenCoder, &rd, posState); - state = state < 7 ? 8 : 11; - } - else - { - int posSlot; - rep3 = rep2; - rep2 = rep1; - rep1 = rep0; - state = state < 7 ? 7 : 10; - len = LzmaLenDecode(p + LenCoder, &rd, posState); - posSlot = RangeDecoderBitTreeDecode(p + PosSlot + - ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << - kNumPosSlotBits), kNumPosSlotBits, &rd); - if (posSlot >= kStartPosModelIndex) - { - int numDirectBits = ((posSlot >> 1) - 1); - rep0 = ((2 | ((UInt32)posSlot & 1)) << numDirectBits); - if (posSlot < kEndPosModelIndex) - { - rep0 += RangeDecoderReverseBitTreeDecode( - p + SpecPos + rep0 - posSlot - 1, numDirectBits, &rd); - } - else - { - rep0 += RangeDecoderDecodeDirectBits(&rd, - numDirectBits - kNumAlignBits) << kNumAlignBits; - rep0 += RangeDecoderReverseBitTreeDecode(p + Align, kNumAlignBits, &rd); - } - } - else - rep0 = posSlot; - if (++rep0 == (UInt32)(0)) - { - /* it's for stream version */ - len = kLzmaStreamWasFinishedId; - break; - } - } - - len += kMatchMinLen; - #ifdef _LZMA_OUT_READ - if (rep0 > distanceLimit) - #else - if (rep0 > nowPos) - #endif - return LZMA_RESULT_DATA_ERROR; - - #ifdef _LZMA_OUT_READ - if (dictionarySize - distanceLimit > (UInt32)len) - distanceLimit += len; - else - distanceLimit = dictionarySize; - #endif - - do - { - #ifdef _LZMA_OUT_READ - UInt32 pos = dictionaryPos - rep0; - if (pos >= dictionarySize) - pos += dictionarySize; - previousByte = dictionary[pos]; - dictionary[dictionaryPos] = previousByte; - if (++dictionaryPos == dictionarySize) - dictionaryPos = 0; - #else - previousByte = outStream[nowPos - rep0]; - #endif - len--; - outStream[nowPos++] = previousByte; - } - while(len != 0 && nowPos < outSize); - } - } - - - #ifdef _LZMA_OUT_READ - vs->Range = rd.Range; - vs->Code = rd.Code; - vs->DictionaryPos = dictionaryPos; - vs->GlobalPos = globalPos + (UInt32)nowPos; - vs->DistanceLimit = distanceLimit; - vs->Reps[0] = rep0; - vs->Reps[1] = rep1; - vs->Reps[2] = rep2; - vs->Reps[3] = rep3; - vs->State = state; - vs->RemainLen = len; - vs->TempDictionary[0] = tempDictionary[0]; - #endif - - #ifdef _LZMA_IN_CB - vs->Buffer = rd.Buffer; - vs->BufferLim = rd.BufferLim; - #else - *inSizeProcessed = (SizeT)(rd.Buffer - inStream); - #endif - *outSizeProcessed = nowPos; - return LZMA_RESULT_OK; -} diff --git a/C/Compress/Lzma/LzmaStateDecode.c b/C/Compress/Lzma/LzmaStateDecode.c deleted file mode 100755 index 5dc8f0e2..00000000 --- a/C/Compress/Lzma/LzmaStateDecode.c +++ /dev/null @@ -1,521 +0,0 @@ -/* - LzmaStateDecode.c - LZMA Decoder (State version) - - LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) - http://www.7-zip.org/ - - LZMA SDK is licensed under two licenses: - 1) GNU Lesser General Public License (GNU LGPL) - 2) Common Public License (CPL) - It means that you can select one of these two licenses and - follow rules of that license. - - SPECIAL EXCEPTION: - Igor Pavlov, as the author of this Code, expressly permits you to - statically or dynamically link your Code (or bind by name) to the - interfaces of this file without subjecting your linked Code to the - terms of the CPL or GNU LGPL. Any modifications or additions - to this file, however, are subject to the LGPL or CPL terms. -*/ - -#include "LzmaStateDecode.h" - -#define kNumTopBits 24 -#define kTopValue ((UInt32)1 << kNumTopBits) - -#define kNumBitModelTotalBits 11 -#define kBitModelTotal (1 << kNumBitModelTotalBits) -#define kNumMoveBits 5 - -#define RC_READ_BYTE (*Buffer++) - -#define RC_INIT Code = 0; Range = 0xFFFFFFFF; \ - { int i; for(i = 0; i < 5; i++) { Code = (Code << 8) | RC_READ_BYTE; }} - -#define RC_NORMALIZE if (Range < kTopValue) { Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; } - -#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound) -#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits; -#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits; - -#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \ - { UpdateBit0(p); mi <<= 1; A0; } else \ - { UpdateBit1(p); mi = (mi + mi) + 1; A1; } - -#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;) - -#define RangeDecoderBitTreeDecode(probs, numLevels, res) \ - { int i = numLevels; res = 1; \ - do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \ - res -= (1 << numLevels); } - - -#define kNumPosBitsMax 4 -#define kNumPosStatesMax (1 << kNumPosBitsMax) - -#define kLenNumLowBits 3 -#define kLenNumLowSymbols (1 << kLenNumLowBits) -#define kLenNumMidBits 3 -#define kLenNumMidSymbols (1 << kLenNumMidBits) -#define kLenNumHighBits 8 -#define kLenNumHighSymbols (1 << kLenNumHighBits) - -#define LenChoice 0 -#define LenChoice2 (LenChoice + 1) -#define LenLow (LenChoice2 + 1) -#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) -#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) -#define kNumLenProbs (LenHigh + kLenNumHighSymbols) - - -#define kNumStates 12 -#define kNumLitStates 7 - -#define kStartPosModelIndex 4 -#define kEndPosModelIndex 14 -#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) - -#define kNumPosSlotBits 6 -#define kNumLenToPosStates 4 - -#define kNumAlignBits 4 -#define kAlignTableSize (1 << kNumAlignBits) - -#define kMatchMinLen 2 - -#define IsMatch 0 -#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) -#define IsRepG0 (IsRep + kNumStates) -#define IsRepG1 (IsRepG0 + kNumStates) -#define IsRepG2 (IsRepG1 + kNumStates) -#define IsRep0Long (IsRepG2 + kNumStates) -#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) -#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) -#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) -#define LenCoder (Align + kAlignTableSize) -#define RepLenCoder (LenCoder + kNumLenProbs) -#define Literal (RepLenCoder + kNumLenProbs) - -#if Literal != LZMA_BASE_SIZE -StopCompilingDueBUG -#endif - -/* kRequiredInBufferSize = number of required input bytes for worst case: - longest match with longest distance. - kLzmaInBufferSize must be larger than kRequiredInBufferSize - 23 bits = 2 (match select) + 10 (len) + 6 (distance) + 4(align) + 1 (RC_NORMALIZE) -*/ - -#define kRequiredInBufferSize ((23 * (kNumBitModelTotalBits - kNumMoveBits + 1) + 26 + 9) / 8) - -#define kLzmaStreamWasFinishedId (-1) - -int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size) -{ - unsigned char prop0; - if (size < LZMA_PROPERTIES_SIZE) - return LZMA_RESULT_DATA_ERROR; - prop0 = propsData[0]; - if (prop0 >= (9 * 5 * 5)) - return LZMA_RESULT_DATA_ERROR; - { - for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5)); - for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9); - propsRes->lc = prop0; - /* - unsigned char remainder = (unsigned char)(prop0 / 9); - propsRes->lc = prop0 % 9; - propsRes->pb = remainder / 5; - propsRes->lp = remainder % 5; - */ - } - - { - int i; - propsRes->DictionarySize = 0; - for (i = 0; i < 4; i++) - propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8); - if (propsRes->DictionarySize == 0) - propsRes->DictionarySize = 1; - return LZMA_RESULT_OK; - } -} - -int LzmaDecode( - CLzmaDecoderState *vs, - const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, - unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed, - int finishDecoding) -{ - UInt32 Range = vs->Range; - UInt32 Code = vs->Code; - - unsigned char *Buffer = vs->Buffer; - int BufferSize = vs->BufferSize; /* don't change it to unsigned int */ - CProb *p = vs->Probs; - - int state = vs->State; - unsigned char previousByte; - UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; - SizeT nowPos = 0; - UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1; - UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1; - int lc = vs->Properties.lc; - int len = vs->RemainLen; - UInt32 globalPos = vs->GlobalPos; - UInt32 distanceLimit = vs->DistanceLimit; - - unsigned char *dictionary = vs->Dictionary; - UInt32 dictionarySize = vs->Properties.DictionarySize; - UInt32 dictionaryPos = vs->DictionaryPos; - - unsigned char tempDictionary[4]; - - (*inSizeProcessed) = 0; - (*outSizeProcessed) = 0; - if (len == kLzmaStreamWasFinishedId) - return LZMA_RESULT_OK; - - if (dictionarySize == 0) - { - dictionary = tempDictionary; - dictionarySize = 1; - tempDictionary[0] = vs->TempDictionary[0]; - } - - if (len == kLzmaNeedInitId) - { - while (inSize > 0 && BufferSize < kLzmaInBufferSize) - { - Buffer[BufferSize++] = *inStream++; - (*inSizeProcessed)++; - inSize--; - } - if (BufferSize < 5) - { - vs->BufferSize = BufferSize; - return finishDecoding ? LZMA_RESULT_DATA_ERROR : LZMA_RESULT_OK; - } - { - UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); - UInt32 i; - for (i = 0; i < numProbs; i++) - p[i] = kBitModelTotal >> 1; - rep0 = rep1 = rep2 = rep3 = 1; - state = 0; - globalPos = 0; - distanceLimit = 0; - dictionaryPos = 0; - dictionary[dictionarySize - 1] = 0; - RC_INIT; - } - len = 0; - } - while(len != 0 && nowPos < outSize) - { - UInt32 pos = dictionaryPos - rep0; - if (pos >= dictionarySize) - pos += dictionarySize; - outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos]; - if (++dictionaryPos == dictionarySize) - dictionaryPos = 0; - len--; - } - if (dictionaryPos == 0) - previousByte = dictionary[dictionarySize - 1]; - else - previousByte = dictionary[dictionaryPos - 1]; - - for (;;) - { - int bufferPos = (int)(Buffer - vs->Buffer); - if (BufferSize - bufferPos < kRequiredInBufferSize) - { - int i; - BufferSize -= bufferPos; - if (BufferSize < 0) - return LZMA_RESULT_DATA_ERROR; - for (i = 0; i < BufferSize; i++) - vs->Buffer[i] = Buffer[i]; - Buffer = vs->Buffer; - while (inSize > 0 && BufferSize < kLzmaInBufferSize) - { - Buffer[BufferSize++] = *inStream++; - (*inSizeProcessed)++; - inSize--; - } - if (BufferSize < kRequiredInBufferSize && !finishDecoding) - break; - } - if (nowPos >= outSize) - break; - { - CProb *prob; - UInt32 bound; - int posState = (int)((nowPos + globalPos) & posStateMask); - - prob = p + IsMatch + (state << kNumPosBitsMax) + posState; - IfBit0(prob) - { - int symbol = 1; - UpdateBit0(prob) - prob = p + Literal + (LZMA_LIT_SIZE * - ((((nowPos + globalPos)& literalPosMask) << lc) + (previousByte >> (8 - lc)))); - - if (state >= kNumLitStates) - { - int matchByte; - UInt32 pos = dictionaryPos - rep0; - if (pos >= dictionarySize) - pos += dictionarySize; - matchByte = dictionary[pos]; - do - { - int bit; - CProb *probLit; - matchByte <<= 1; - bit = (matchByte & 0x100); - probLit = prob + 0x100 + bit + symbol; - RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break) - } - while (symbol < 0x100); - } - while (symbol < 0x100) - { - CProb *probLit = prob + symbol; - RC_GET_BIT(probLit, symbol) - } - previousByte = (unsigned char)symbol; - - outStream[nowPos++] = previousByte; - if (distanceLimit < dictionarySize) - distanceLimit++; - - dictionary[dictionaryPos] = previousByte; - if (++dictionaryPos == dictionarySize) - dictionaryPos = 0; - if (state < 4) state = 0; - else if (state < 10) state -= 3; - else state -= 6; - } - else - { - UpdateBit1(prob); - prob = p + IsRep + state; - IfBit0(prob) - { - UpdateBit0(prob); - rep3 = rep2; - rep2 = rep1; - rep1 = rep0; - state = state < kNumLitStates ? 0 : 3; - prob = p + LenCoder; - } - else - { - UpdateBit1(prob); - prob = p + IsRepG0 + state; - IfBit0(prob) - { - UpdateBit0(prob); - prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState; - IfBit0(prob) - { - UInt32 pos; - UpdateBit0(prob); - if (distanceLimit == 0) - return LZMA_RESULT_DATA_ERROR; - if (distanceLimit < dictionarySize) - distanceLimit++; - state = state < kNumLitStates ? 9 : 11; - pos = dictionaryPos - rep0; - if (pos >= dictionarySize) - pos += dictionarySize; - previousByte = dictionary[pos]; - dictionary[dictionaryPos] = previousByte; - if (++dictionaryPos == dictionarySize) - dictionaryPos = 0; - outStream[nowPos++] = previousByte; - continue; - } - else - { - UpdateBit1(prob); - } - } - else - { - UInt32 distance; - UpdateBit1(prob); - prob = p + IsRepG1 + state; - IfBit0(prob) - { - UpdateBit0(prob); - distance = rep1; - } - else - { - UpdateBit1(prob); - prob = p + IsRepG2 + state; - IfBit0(prob) - { - UpdateBit0(prob); - distance = rep2; - } - else - { - UpdateBit1(prob); - distance = rep3; - rep3 = rep2; - } - rep2 = rep1; - } - rep1 = rep0; - rep0 = distance; - } - state = state < kNumLitStates ? 8 : 11; - prob = p + RepLenCoder; - } - { - int numBits, offset; - CProb *probLen = prob + LenChoice; - IfBit0(probLen) - { - UpdateBit0(probLen); - probLen = prob + LenLow + (posState << kLenNumLowBits); - offset = 0; - numBits = kLenNumLowBits; - } - else - { - UpdateBit1(probLen); - probLen = prob + LenChoice2; - IfBit0(probLen) - { - UpdateBit0(probLen); - probLen = prob + LenMid + (posState << kLenNumMidBits); - offset = kLenNumLowSymbols; - numBits = kLenNumMidBits; - } - else - { - UpdateBit1(probLen); - probLen = prob + LenHigh; - offset = kLenNumLowSymbols + kLenNumMidSymbols; - numBits = kLenNumHighBits; - } - } - RangeDecoderBitTreeDecode(probLen, numBits, len); - len += offset; - } - - if (state < 4) - { - int posSlot; - state += kNumLitStates; - prob = p + PosSlot + - ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << - kNumPosSlotBits); - RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot); - if (posSlot >= kStartPosModelIndex) - { - int numDirectBits = ((posSlot >> 1) - 1); - rep0 = (2 | ((UInt32)posSlot & 1)); - if (posSlot < kEndPosModelIndex) - { - rep0 <<= numDirectBits; - prob = p + SpecPos + rep0 - posSlot - 1; - } - else - { - numDirectBits -= kNumAlignBits; - do - { - RC_NORMALIZE - Range >>= 1; - rep0 <<= 1; - if (Code >= Range) - { - Code -= Range; - rep0 |= 1; - } - } - while (--numDirectBits != 0); - prob = p + Align; - rep0 <<= kNumAlignBits; - numDirectBits = kNumAlignBits; - } - { - int i = 1; - int mi = 1; - do - { - CProb *prob3 = prob + mi; - RC_GET_BIT2(prob3, mi, ; , rep0 |= i); - i <<= 1; - } - while(--numDirectBits != 0); - } - } - else - rep0 = posSlot; - if (++rep0 == (UInt32)(0)) - { - /* it's for stream version */ - len = kLzmaStreamWasFinishedId; - break; - } - } - - len += kMatchMinLen; - if (rep0 > distanceLimit) - return LZMA_RESULT_DATA_ERROR; - if (dictionarySize - distanceLimit > (UInt32)len) - distanceLimit += len; - else - distanceLimit = dictionarySize; - - do - { - UInt32 pos = dictionaryPos - rep0; - if (pos >= dictionarySize) - pos += dictionarySize; - previousByte = dictionary[pos]; - dictionary[dictionaryPos] = previousByte; - if (++dictionaryPos == dictionarySize) - dictionaryPos = 0; - len--; - outStream[nowPos++] = previousByte; - } - while(len != 0 && nowPos < outSize); - } - } - } - RC_NORMALIZE; - - BufferSize -= (int)(Buffer - vs->Buffer); - if (BufferSize < 0) - return LZMA_RESULT_DATA_ERROR; - { - int i; - for (i = 0; i < BufferSize; i++) - vs->Buffer[i] = Buffer[i]; - } - vs->BufferSize = BufferSize; - vs->Range = Range; - vs->Code = Code; - vs->DictionaryPos = dictionaryPos; - vs->GlobalPos = (UInt32)(globalPos + nowPos); - vs->DistanceLimit = distanceLimit; - vs->Reps[0] = rep0; - vs->Reps[1] = rep1; - vs->Reps[2] = rep2; - vs->Reps[3] = rep3; - vs->State = state; - vs->RemainLen = len; - vs->TempDictionary[0] = tempDictionary[0]; - - (*outSizeProcessed) = nowPos; - return LZMA_RESULT_OK; -} diff --git a/C/Compress/Lzma/LzmaStateDecode.h b/C/Compress/Lzma/LzmaStateDecode.h deleted file mode 100755 index 26490d61..00000000 --- a/C/Compress/Lzma/LzmaStateDecode.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - LzmaStateDecode.h - LZMA Decoder interface (State version) - - LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) - http://www.7-zip.org/ - - LZMA SDK is licensed under two licenses: - 1) GNU Lesser General Public License (GNU LGPL) - 2) Common Public License (CPL) - It means that you can select one of these two licenses and - follow rules of that license. - - SPECIAL EXCEPTION: - Igor Pavlov, as the author of this code, expressly permits you to - statically or dynamically link your code (or bind by name) to the - interfaces of this file without subjecting your linked code to the - terms of the CPL or GNU LGPL. Any modifications or additions - to this file, however, are subject to the LGPL or CPL terms. -*/ - -#ifndef __LZMASTATEDECODE_H -#define __LZMASTATEDECODE_H - -#include "LzmaTypes.h" - -/* #define _LZMA_PROB32 */ -/* It can increase speed on some 32-bit CPUs, - but memory usage will be doubled in that case */ - -#ifdef _LZMA_PROB32 -#define CProb UInt32 -#else -#define CProb UInt16 -#endif - -#define LZMA_RESULT_OK 0 -#define LZMA_RESULT_DATA_ERROR 1 - -#define LZMA_BASE_SIZE 1846 -#define LZMA_LIT_SIZE 768 - -#define LZMA_PROPERTIES_SIZE 5 - -typedef struct _CLzmaProperties -{ - int lc; - int lp; - int pb; - UInt32 DictionarySize; -}CLzmaProperties; - -int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size); - -#define LzmaGetNumProbs(lzmaProps) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((lzmaProps)->lc + (lzmaProps)->lp))) - -#define kLzmaInBufferSize 64 /* don't change it. it must be larger than kRequiredInBufferSize */ - -#define kLzmaNeedInitId (-2) - -typedef struct _CLzmaDecoderState -{ - CLzmaProperties Properties; - CProb *Probs; - unsigned char *Dictionary; - - unsigned char Buffer[kLzmaInBufferSize]; - int BufferSize; - - UInt32 Range; - UInt32 Code; - UInt32 DictionaryPos; - UInt32 GlobalPos; - UInt32 DistanceLimit; - UInt32 Reps[4]; - int State; - int RemainLen; /* -2: decoder needs internal initialization - -1: stream was finished, - 0: ok - > 0: need to write RemainLen bytes as match Reps[0], - */ - unsigned char TempDictionary[4]; /* it's required when DictionarySize = 0 */ -} CLzmaDecoderState; - -#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; (vs)->BufferSize = 0; } - -/* LzmaDecode: decoding from input stream to output stream. - If finishDecoding != 0, then there are no more bytes in input stream - after inStream[inSize - 1]. */ - -int LzmaDecode(CLzmaDecoderState *vs, - const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, - unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed, - int finishDecoding); - -#endif diff --git a/C/Compress/Lzma/LzmaStateTest.c b/C/Compress/Lzma/LzmaStateTest.c deleted file mode 100755 index 5df4e438..00000000 --- a/C/Compress/Lzma/LzmaStateTest.c +++ /dev/null @@ -1,195 +0,0 @@ -/* -LzmaStateTest.c -Test application for LZMA Decoder (State version) - -This file written and distributed to public domain by Igor Pavlov. -This file is part of LZMA SDK 4.26 (2005-08-02) -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "LzmaStateDecode.h" - -const char *kCantReadMessage = "Can not read input file"; -const char *kCantWriteMessage = "Can not write output file"; -const char *kCantAllocateMessage = "Can not allocate memory"; - -#define kInBufferSize (1 << 15) -#define kOutBufferSize (1 << 15) - -unsigned char g_InBuffer[kInBufferSize]; -unsigned char g_OutBuffer[kOutBufferSize]; - -size_t MyReadFile(FILE *file, void *data, size_t size) - { return fread(data, 1, size, file); } - -int MyReadFileAndCheck(FILE *file, void *data, size_t size) - { return (MyReadFile(file, data, size) == size); } - -int PrintError(char *buffer, const char *message) -{ - sprintf(buffer + strlen(buffer), "\nError: "); - sprintf(buffer + strlen(buffer), message); - return 1; -} - -int main3(FILE *inFile, FILE *outFile, char *rs) -{ - /* We use two 32-bit integers to construct 64-bit integer for file size. - You can remove outSizeHigh, if you don't need >= 4GB supporting, - or you can use UInt64 outSize, if your compiler supports 64-bit integers*/ - UInt32 outSize = 0; - UInt32 outSizeHigh = 0; - - int waitEOS = 1; - /* waitEOS = 1, if there is no uncompressed size in headers, - so decoder will wait EOS (End of Stream Marker) in compressed stream */ - - int i; - int res = 0; - CLzmaDecoderState state; /* it's about 140 bytes structure, if int is 32-bit */ - unsigned char properties[LZMA_PROPERTIES_SIZE]; - SizeT inAvail = 0; - unsigned char *inBuffer = 0; - - if (sizeof(UInt32) < 4) - return PrintError(rs, "LZMA decoder needs correct UInt32"); - - /* Read LZMA properties for compressed stream */ - - if (!MyReadFileAndCheck(inFile, properties, sizeof(properties))) - return PrintError(rs, kCantReadMessage); - - /* Read uncompressed size */ - - for (i = 0; i < 8; i++) - { - unsigned char b; - if (!MyReadFileAndCheck(inFile, &b, 1)) - return PrintError(rs, kCantReadMessage); - if (b != 0xFF) - waitEOS = 0; - if (i < 4) - outSize += (UInt32)(b) << (i * 8); - else - outSizeHigh += (UInt32)(b) << ((i - 4) * 8); - } - - /* Decode LZMA properties and allocate memory */ - - if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK) - return PrintError(rs, "Incorrect stream properties"); - state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb)); - if (state.Probs == 0) - return PrintError(rs, kCantAllocateMessage); - - if (state.Properties.DictionarySize == 0) - state.Dictionary = 0; - else - { - state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize); - if (state.Dictionary == 0) - { - free(state.Probs); - return PrintError(rs, kCantAllocateMessage); - } - } - - /* Decompress */ - - LzmaDecoderInit(&state); - - do - { - SizeT inProcessed, outProcessed; - int finishDecoding; - UInt32 outAvail = kOutBufferSize; - if (!waitEOS && outSizeHigh == 0 && outAvail > outSize) - outAvail = outSize; - if (inAvail == 0) - { - inAvail = (SizeT)MyReadFile(inFile, g_InBuffer, kInBufferSize); - inBuffer = g_InBuffer; - } - finishDecoding = (inAvail == 0); - res = LzmaDecode(&state, - inBuffer, inAvail, &inProcessed, - g_OutBuffer, outAvail, &outProcessed, - finishDecoding); - if (res != 0) - { - sprintf(rs + strlen(rs), "\nDecoding error = %d\n", res); - res = 1; - break; - } - inAvail -= inProcessed; - inBuffer += inProcessed; - - if (outFile != 0) - if (fwrite(g_OutBuffer, 1, outProcessed, outFile) != outProcessed) - { - PrintError(rs, kCantWriteMessage); - res = 1; - break; - } - - if (outSize < outProcessed) - outSizeHigh--; - outSize -= (UInt32)outProcessed; - outSize &= 0xFFFFFFFF; - - if (outProcessed == 0 && finishDecoding) - { - if (!waitEOS && (outSize != 0 || outSizeHigh != 0)) - res = 1; - break; - } - } - while ((outSize != 0 && outSizeHigh == 0) || outSizeHigh != 0 || waitEOS); - - free(state.Dictionary); - free(state.Probs); - return res; -} - -int main2(int numArgs, const char *args[], char *rs) -{ - FILE *inFile = 0; - FILE *outFile = 0; - int res; - - sprintf(rs + strlen(rs), "\nLZMA Decoder 4.26 Copyright (c) 1999-2005 Igor Pavlov 2005-08-02\n"); - if (numArgs < 2 || numArgs > 3) - { - sprintf(rs + strlen(rs), "\nUsage: lzmadec file.lzma [outFile]\n"); - return 1; - } - - inFile = fopen(args[1], "rb"); - if (inFile == 0) - return PrintError(rs, "Can not open input file"); - - if (numArgs > 2) - { - outFile = fopen(args[2], "wb+"); - if (outFile == 0) - return PrintError(rs, "Can not open output file"); - } - - res = main3(inFile, outFile, rs); - - if (outFile != 0) - fclose(outFile); - fclose(inFile); - return res; -} - -int main(int numArgs, const char *args[]) -{ - char rs[800] = { 0 }; - int res = main2(numArgs, args, rs); - printf(rs); - return res; -} diff --git a/C/Compress/Lzma/LzmaTest.c b/C/Compress/Lzma/LzmaTest.c deleted file mode 100755 index f95a753b..00000000 --- a/C/Compress/Lzma/LzmaTest.c +++ /dev/null @@ -1,342 +0,0 @@ -/* -LzmaTest.c -Test application for LZMA Decoder - -This file written and distributed to public domain by Igor Pavlov. -This file is part of LZMA SDK 4.26 (2005-08-05) -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "LzmaDecode.h" - -const char *kCantReadMessage = "Can not read input file"; -const char *kCantWriteMessage = "Can not write output file"; -const char *kCantAllocateMessage = "Can not allocate memory"; - -size_t MyReadFile(FILE *file, void *data, size_t size) -{ - if (size == 0) - return 0; - return fread(data, 1, size, file); -} - -int MyReadFileAndCheck(FILE *file, void *data, size_t size) - { return (MyReadFile(file, data, size) == size);} - -size_t MyWriteFile(FILE *file, const void *data, size_t size) -{ - if (size == 0) - return 0; - return fwrite(data, 1, size, file); -} - -int MyWriteFileAndCheck(FILE *file, const void *data, size_t size) - { return (MyWriteFile(file, data, size) == size); } - -#ifdef _LZMA_IN_CB -#define kInBufferSize (1 << 15) -typedef struct _CBuffer -{ - ILzmaInCallback InCallback; - FILE *File; - unsigned char Buffer[kInBufferSize]; -} CBuffer; - -int LzmaReadCompressed(void *object, const unsigned char **buffer, SizeT *size) -{ - CBuffer *b = (CBuffer *)object; - *buffer = b->Buffer; - *size = (SizeT)MyReadFile(b->File, b->Buffer, kInBufferSize); - return LZMA_RESULT_OK; -} -CBuffer g_InBuffer; - -#endif - -#ifdef _LZMA_OUT_READ -#define kOutBufferSize (1 << 15) -unsigned char g_OutBuffer[kOutBufferSize]; -#endif - -int PrintError(char *buffer, const char *message) -{ - sprintf(buffer + strlen(buffer), "\nError: "); - sprintf(buffer + strlen(buffer), message); - return 1; -} - -int main3(FILE *inFile, FILE *outFile, char *rs) -{ - /* We use two 32-bit integers to construct 64-bit integer for file size. - You can remove outSizeHigh, if you don't need >= 4GB supporting, - or you can use UInt64 outSize, if your compiler supports 64-bit integers*/ - UInt32 outSize = 0; - UInt32 outSizeHigh = 0; - #ifndef _LZMA_OUT_READ - SizeT outSizeFull; - unsigned char *outStream; - #endif - - int waitEOS = 1; - /* waitEOS = 1, if there is no uncompressed size in headers, - so decoder will wait EOS (End of Stream Marker) in compressed stream */ - - #ifndef _LZMA_IN_CB - SizeT compressedSize; - unsigned char *inStream; - #endif - - CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */ - unsigned char properties[LZMA_PROPERTIES_SIZE]; - - int res; - - #ifdef _LZMA_IN_CB - g_InBuffer.File = inFile; - #endif - - if (sizeof(UInt32) < 4) - return PrintError(rs, "LZMA decoder needs correct UInt32"); - - #ifndef _LZMA_IN_CB - { - long length; - fseek(inFile, 0, SEEK_END); - length = ftell(inFile); - fseek(inFile, 0, SEEK_SET); - if ((long)(SizeT)length != length) - return PrintError(rs, "Too big compressed stream"); - compressedSize = (SizeT)(length - (LZMA_PROPERTIES_SIZE + 8)); - } - #endif - - /* Read LZMA properties for compressed stream */ - - if (!MyReadFileAndCheck(inFile, properties, sizeof(properties))) - return PrintError(rs, kCantReadMessage); - - /* Read uncompressed size */ - - { - int i; - for (i = 0; i < 8; i++) - { - unsigned char b; - if (!MyReadFileAndCheck(inFile, &b, 1)) - return PrintError(rs, kCantReadMessage); - if (b != 0xFF) - waitEOS = 0; - if (i < 4) - outSize += (UInt32)(b) << (i * 8); - else - outSizeHigh += (UInt32)(b) << ((i - 4) * 8); - } - - #ifndef _LZMA_OUT_READ - if (waitEOS) - return PrintError(rs, "Stream with EOS marker is not supported"); - outSizeFull = (SizeT)outSize; - if (sizeof(SizeT) >= 8) - outSizeFull |= (((SizeT)outSizeHigh << 16) << 16); - else if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize) - return PrintError(rs, "Too big uncompressed stream"); - #endif - } - - /* Decode LZMA properties and allocate memory */ - - if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK) - return PrintError(rs, "Incorrect stream properties"); - state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb)); - - #ifdef _LZMA_OUT_READ - if (state.Properties.DictionarySize == 0) - state.Dictionary = 0; - else - state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize); - #else - if (outSizeFull == 0) - outStream = 0; - else - outStream = (unsigned char *)malloc(outSizeFull); - #endif - - #ifndef _LZMA_IN_CB - if (compressedSize == 0) - inStream = 0; - else - inStream = (unsigned char *)malloc(compressedSize); - #endif - - if (state.Probs == 0 - #ifdef _LZMA_OUT_READ - || (state.Dictionary == 0 && state.Properties.DictionarySize != 0) - #else - || (outStream == 0 && outSizeFull != 0) - #endif - #ifndef _LZMA_IN_CB - || (inStream == 0 && compressedSize != 0) - #endif - ) - { - free(state.Probs); - #ifdef _LZMA_OUT_READ - free(state.Dictionary); - #else - free(outStream); - #endif - #ifndef _LZMA_IN_CB - free(inStream); - #endif - return PrintError(rs, kCantAllocateMessage); - } - - /* Decompress */ - - #ifdef _LZMA_IN_CB - g_InBuffer.InCallback.Read = LzmaReadCompressed; - #else - if (!MyReadFileAndCheck(inFile, inStream, compressedSize)) - return PrintError(rs, kCantReadMessage); - #endif - - #ifdef _LZMA_OUT_READ - { - #ifndef _LZMA_IN_CB - SizeT inAvail = compressedSize; - const unsigned char *inBuffer = inStream; - #endif - LzmaDecoderInit(&state); - do - { - #ifndef _LZMA_IN_CB - SizeT inProcessed; - #endif - SizeT outProcessed; - SizeT outAvail = kOutBufferSize; - if (!waitEOS && outSizeHigh == 0 && outAvail > outSize) - outAvail = (SizeT)outSize; - res = LzmaDecode(&state, - #ifdef _LZMA_IN_CB - &g_InBuffer.InCallback, - #else - inBuffer, inAvail, &inProcessed, - #endif - g_OutBuffer, outAvail, &outProcessed); - if (res != 0) - { - sprintf(rs + strlen(rs), "\nDecoding error = %d\n", res); - res = 1; - break; - } - #ifndef _LZMA_IN_CB - inAvail -= inProcessed; - inBuffer += inProcessed; - #endif - - if (outFile != 0) - if (!MyWriteFileAndCheck(outFile, g_OutBuffer, (size_t)outProcessed)) - { - PrintError(rs, kCantWriteMessage); - res = 1; - break; - } - - if (outSize < outProcessed) - outSizeHigh--; - outSize -= (UInt32)outProcessed; - outSize &= 0xFFFFFFFF; - - if (outProcessed == 0) - { - if (!waitEOS && (outSize != 0 || outSizeHigh != 0)) - res = 1; - break; - } - } - while ((outSize != 0 && outSizeHigh == 0) || outSizeHigh != 0 || waitEOS); - } - - #else - { - #ifndef _LZMA_IN_CB - SizeT inProcessed; - #endif - SizeT outProcessed; - res = LzmaDecode(&state, - #ifdef _LZMA_IN_CB - &g_InBuffer.InCallback, - #else - inStream, compressedSize, &inProcessed, - #endif - outStream, outSizeFull, &outProcessed); - if (res != 0) - { - sprintf(rs + strlen(rs), "\nDecoding error = %d\n", res); - res = 1; - } - else if (outFile != 0) - { - if (!MyWriteFileAndCheck(outFile, outStream, (size_t)outProcessed)) - { - PrintError(rs, kCantWriteMessage); - res = 1; - } - } - } - #endif - - free(state.Probs); - #ifdef _LZMA_OUT_READ - free(state.Dictionary); - #else - free(outStream); - #endif - #ifndef _LZMA_IN_CB - free(inStream); - #endif - return res; -} - -int main2(int numArgs, const char *args[], char *rs) -{ - FILE *inFile = 0; - FILE *outFile = 0; - int res; - - sprintf(rs + strlen(rs), "\nLZMA Decoder 4.26 Copyright (c) 1999-2005 Igor Pavlov 2005-08-05\n"); - if (numArgs < 2 || numArgs > 3) - { - sprintf(rs + strlen(rs), "\nUsage: lzmadec file.lzma [outFile]\n"); - return 1; - } - - inFile = fopen(args[1], "rb"); - if (inFile == 0) - return PrintError(rs, "Can not open input file"); - - if (numArgs > 2) - { - outFile = fopen(args[2], "wb+"); - if (outFile == 0) - return PrintError(rs, "Can not open output file"); - } - - res = main3(inFile, outFile, rs); - - if (outFile != 0) - fclose(outFile); - fclose(inFile); - return res; -} - -int main(int numArgs, const char *args[]) -{ - char rs[800] = { 0 }; - int res = main2(numArgs, args, rs); - printf(rs); - return res; -} diff --git a/C/Compress/Lzma/LzmaTypes.h b/C/Compress/Lzma/LzmaTypes.h deleted file mode 100755 index 9c272907..00000000 --- a/C/Compress/Lzma/LzmaTypes.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -LzmaTypes.h - -Types for LZMA Decoder - -This file written and distributed to public domain by Igor Pavlov. -This file is part of LZMA SDK 4.40 (2006-05-01) -*/ - -#ifndef __LZMATYPES_H -#define __LZMATYPES_H - -#ifndef _7ZIP_BYTE_DEFINED -#define _7ZIP_BYTE_DEFINED -typedef unsigned char Byte; -#endif - -#ifndef _7ZIP_UINT16_DEFINED -#define _7ZIP_UINT16_DEFINED -typedef unsigned short UInt16; -#endif - -#ifndef _7ZIP_UINT32_DEFINED -#define _7ZIP_UINT32_DEFINED -#ifdef _LZMA_UINT32_IS_ULONG -typedef unsigned long UInt32; -#else -typedef unsigned int UInt32; -#endif -#endif - -/* #define _LZMA_NO_SYSTEM_SIZE_T */ -/* You can use it, if you don't want <stddef.h> */ - -#ifndef _7ZIP_SIZET_DEFINED -#define _7ZIP_SIZET_DEFINED -#ifdef _LZMA_NO_SYSTEM_SIZE_T -typedef UInt32 SizeT; -#else -#include <stddef.h> -typedef size_t SizeT; -#endif -#endif - -#endif diff --git a/C/CpuArch.h b/C/CpuArch.h index 26ce8b1d..2ec7081f 100755 --- a/C/CpuArch.h +++ b/C/CpuArch.h @@ -1,4 +1,7 @@ -/* CpuArch.h */ +/* CpuArch.h +2008-03-26 +Igor Pavlov +Public domain */ #ifndef __CPUARCH_H #define __CPUARCH_H @@ -15,4 +18,31 @@ about these properties of platform. #define LITTLE_ENDIAN_UNALIGN #endif +#ifdef LITTLE_ENDIAN_UNALIGN + +#define GetUi16(p) (*(const UInt16 *)(p)) +#define GetUi32(p) (*(const UInt32 *)(p)) +#define GetUi64(p) (*(const UInt64 *)(p)) +#define SetUi32(p, d) *(UInt32 *)(p) = d; + +#else + +#define GetUi16(p) (((const Byte *)(p))[0] | \ + ((UInt16)((const Byte *)(p))[1] << 8)) + +#define GetUi32(p) (((const Byte *)(p))[0] | \ + ((UInt32)((const Byte *)(p))[1] << 8 ) | \ + ((UInt32)((const Byte *)(p))[2] << 16) | \ + ((UInt32)((const Byte *)(p))[3] << 24)) + +#define GetUi64(p) (GetUi32(p) | (UInt64)GetUi32(((const Byte *)(p)) + 4) << 32) + +#define SetUi32(p, d) { UInt32 _x_ = (d); \ + ((Byte *)(p))[0] = (Byte)_x_; \ + ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \ + ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \ + ((Byte *)(p))[3] = (Byte)(_x_ >> 24); } + +#endif + #endif diff --git a/C/Crypto/Aes.h b/C/Crypto/Aes.h deleted file mode 100755 index ab51a72c..00000000 --- a/C/Crypto/Aes.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Aes.h */ - -#ifndef __AES_H -#define __AES_H - -#include "../Types.h" - -#define AES_BLOCK_SIZE 16 - -typedef struct _CAes -{ - unsigned numRounds2; /* = numRounds / 2 */ - UInt32 rkey[(14 + 1) * 4]; -} CAes; - -/* Call AesGenTables one time before other AES functions */ -void MY_FAST_CALL AesGenTables(void); - -/* keySize = 16 or 24 or 32 */ -void MY_FAST_CALL AesSetKeyEncode(CAes *p, const Byte *key, unsigned keySize); -void MY_FAST_CALL AesSetKeyDecode(CAes *p, const Byte *key, unsigned keySize); - -/* -AesEncode32 and AesDecode32 functions work with little-endian words. -src and dest can contain same address -*/ -void MY_FAST_CALL AesEncode32(const UInt32 *src, UInt32 *dest, const UInt32 *w, unsigned numRounds2); -void MY_FAST_CALL AesDecode32(const UInt32 *src, UInt32 *dest, const UInt32 *w, unsigned numRounds2); - -typedef struct _CAesCbc -{ - UInt32 prev[4]; - CAes aes; -} CAesCbc; - -void MY_FAST_CALL AesCbcInit(CAesCbc *cbc, const Byte *iv); /* iv size is AES_BLOCK_SIZE */ -UInt32 MY_FAST_CALL AesCbcDecode(CAesCbc *cbc, Byte *data, UInt32 size); -UInt32 MY_FAST_CALL AesCbcEncode(CAesCbc *cbc, Byte *data, UInt32 size); - -#endif diff --git a/C/Compress/Huffman/HuffmanEncode.c b/C/HuffEnc.c index f27607e6..65f5d27a 100755 --- a/C/Compress/Huffman/HuffmanEncode.c +++ b/C/HuffEnc.c @@ -1,7 +1,10 @@ -/* Compress/HuffmanEncode.c */ +/* HuffEnc.c -- functions for Huffman encoding +2008-03-26 +Igor Pavlov +Public domain */ -#include "HuffmanEncode.h" -#include "../../Sort.h" +#include "HuffEnc.h" +#include "Sort.h" #define kMaxLen 16 #define NUM_BITS 10 @@ -9,7 +12,6 @@ #define NUM_COUNTERS 64 -/* use BLOCK_SORT_EXTERNAL_FLAGS if blockSize > 1M */ #define HUFFMAN_SPEED_OPT void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymbols, UInt32 maxLen) @@ -69,7 +71,7 @@ void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymb int maxCode = 1; if (num == 1) { - maxCode = p[0] & MASK; + maxCode = (int)(p[0] & MASK); if (maxCode == 0) maxCode++; } diff --git a/C/Compress/Huffman/HuffmanEncode.h b/C/HuffEnc.h index c8acc283..00dd9aca 100755 --- a/C/Compress/Huffman/HuffmanEncode.h +++ b/C/HuffEnc.h @@ -1,9 +1,12 @@ -/* Compress/HuffmanEncode.h */ +/* HuffEnc.h -- functions for Huffman encoding +2008-03-26 +Igor Pavlov +Public domain */ -#ifndef __COMPRESS_HUFFMANENCODE_H -#define __COMPRESS_HUFFMANENCODE_H +#ifndef __HUFFENC_H +#define __HUFFENC_H -#include "../../Types.h" +#include "Types.h" /* Conditions: diff --git a/C/IStream.h b/C/IStream.h deleted file mode 100755 index 58218487..00000000 --- a/C/IStream.h +++ /dev/null @@ -1,19 +0,0 @@ -/* IStream.h */ - -#ifndef __C_ISTREAM_H -#define __C_ISTREAM_H - -#include "Types.h" - -typedef struct _ISeqInStream -{ - HRes (*Read)(void *object, void *data, UInt32 size, UInt32 *processedSize); -} ISeqInStream; - -typedef struct _ISzAlloc -{ - void *(*Alloc)(size_t size); - void (*Free)(void *address); /* address can be 0 */ -} ISzAlloc; - -#endif diff --git a/C/Compress/Lz/MatchFinder.c b/C/LzFind.c index 0f530fc1..831f0e47 100755 --- a/C/Compress/Lz/MatchFinder.c +++ b/C/LzFind.c @@ -1,13 +1,13 @@ -/* MatchFinder.c */ -/* Please call InitCrcTable before */ +/* LzFind.c -- Match finder for LZ algorithms +2008-04-04 +Copyright (c) 1999-2008 Igor Pavlov +Read LzFind.h for license options */ #include <string.h> -#include "MatchFinder.h" +#include "LzFind.h" #include "LzHash.h" -#include "../../7zCrc.h" - #define kEmptyHashValue 0 #define kMaxValForNormalize ((UInt32)0xFFFFFFFF) #define kNormalizeStepMin (1 << 10) /* it must be power of 2 */ @@ -16,18 +16,18 @@ #define kStartMaxLen 3 -void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) +static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) { if (!p->directInput) { - alloc->Free(p->bufferBase); + alloc->Free(alloc, p->bufferBase); p->bufferBase = 0; } } /* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */ -int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) +static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) { UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; if (p->directInput) @@ -39,7 +39,7 @@ int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) { LzInWindow_Free(p, alloc); p->blockSize = blockSize; - p->bufferBase = (Byte *)alloc->Alloc(blockSize); + p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize); } return (p->bufferBase != 0); } @@ -56,26 +56,25 @@ void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) p->streamPos -= subValue; } -void MatchFinder_ReadBlock(CMatchFinder *p) +static void MatchFinder_ReadBlock(CMatchFinder *p) { if (p->streamEndWasReached || p->result != SZ_OK) return; for (;;) { Byte *dest = p->buffer + (p->streamPos - p->pos); - UInt32 numReadBytes; - UInt32 size = (UInt32)(p->bufferBase + p->blockSize - dest); + size_t size = (p->bufferBase + p->blockSize - dest); if (size == 0) return; - p->result = p->stream->Read(p->stream, dest, size, &numReadBytes); + p->result = p->stream->Read(p->stream, dest, &size); if (p->result != SZ_OK) return; - if (numReadBytes == 0) + if (size == 0) { p->streamEndWasReached = 1; return; } - p->streamPos += numReadBytes; + p->streamPos += (UInt32)size; if (p->streamPos - p->pos > p->keepSizeAfter) return; } @@ -85,7 +84,7 @@ void MatchFinder_MoveBlock(CMatchFinder *p) { memmove(p->bufferBase, p->buffer - p->keepSizeBefore, - p->streamPos - p->pos + p->keepSizeBefore); + (size_t)(p->streamPos - p->pos + p->keepSizeBefore)); p->buffer = p->bufferBase + p->keepSizeBefore; } @@ -103,14 +102,14 @@ void MatchFinder_ReadIfRequired(CMatchFinder *p) MatchFinder_ReadBlock(p); } -void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p) +static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p) { if (MatchFinder_NeedMove(p)) MatchFinder_MoveBlock(p); MatchFinder_ReadBlock(p); } -void MatchFinder_SetDefaultSettings(CMatchFinder *p) +static void MatchFinder_SetDefaultSettings(CMatchFinder *p) { p->cutValue = 32; p->btMode = 1; @@ -120,17 +119,29 @@ void MatchFinder_SetDefaultSettings(CMatchFinder *p) p->bigHash = 0; } +#define kCrcPoly 0xEDB88320 + void MatchFinder_Construct(CMatchFinder *p) { + UInt32 i; p->bufferBase = 0; p->directInput = 0; p->hash = 0; MatchFinder_SetDefaultSettings(p); + + for (i = 0; i < 256; i++) + { + UInt32 r = i; + int j; + for (j = 0; j < 8; j++) + r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); + p->crc[i] = r; + } } -void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) +static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) { - alloc->Free(p->hash); + alloc->Free(alloc, p->hash); p->hash = 0; } @@ -140,12 +151,12 @@ void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) LzInWindow_Free(p, alloc); } -CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc) +static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc) { size_t sizeInBytes = (size_t)num * sizeof(CLzRef); if (sizeInBytes / sizeof(CLzRef) != num) return 0; - return (CLzRef *)alloc->Alloc(sizeInBytes); + return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); } int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, @@ -224,7 +235,7 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, return 0; } -void MatchFinder_SetLimits(CMatchFinder *p) +static void MatchFinder_SetLimits(CMatchFinder *p) { UInt32 limit = kMaxValForNormalize - p->pos; UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos; @@ -263,7 +274,7 @@ void MatchFinder_Init(CMatchFinder *p) MatchFinder_SetLimits(p); } -UInt32 MatchFinder_GetSubValue(CMatchFinder *p) +static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) { return (p->pos - p->historySize - 1) & kNormalizeMask; } @@ -282,14 +293,14 @@ void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) } } -void MatchFinder_Normalize(CMatchFinder *p) +static void MatchFinder_Normalize(CMatchFinder *p) { UInt32 subValue = MatchFinder_GetSubValue(p); MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons); MatchFinder_ReduceOffsets(p, subValue); } -void MatchFinder_CheckLimits(CMatchFinder *p) +static void MatchFinder_CheckLimits(CMatchFinder *p) { if (p->pos == kMaxValForNormalize) MatchFinder_Normalize(p); @@ -300,7 +311,7 @@ void MatchFinder_CheckLimits(CMatchFinder *p) MatchFinder_SetLimits(p); } -UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, +static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, UInt32 *distances, UInt32 maxLen) { @@ -386,7 +397,7 @@ UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byt } } -void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, +static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue) { CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; @@ -443,7 +454,7 @@ void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *c #define MOVE_POS_RET MOVE_POS return offset; -void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } +static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } #define GET_MATCHES_HEADER2(minLen, ret_op) \ UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \ @@ -462,7 +473,7 @@ void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } #define SKIP_FOOTER \ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; -UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) { UInt32 offset; GET_MATCHES_HEADER(2) @@ -484,7 +495,7 @@ UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) GET_MATCHES_FOOTER(offset, 2) } -UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) { UInt32 hash2Value, delta2, maxLen, offset; GET_MATCHES_HEADER(3) @@ -517,7 +528,7 @@ UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) GET_MATCHES_FOOTER(offset, maxLen) } -UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) { UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; GET_MATCHES_HEADER(4) @@ -564,7 +575,7 @@ UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) GET_MATCHES_FOOTER(offset, maxLen) } -UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) { UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; GET_MATCHES_HEADER(4) @@ -625,7 +636,7 @@ UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) MOVE_POS_RET } -void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) { do { @@ -651,7 +662,7 @@ void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) while (--num != 0); } -void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) { do { @@ -666,7 +677,7 @@ void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) while (--num != 0); } -void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) { do { @@ -682,7 +693,7 @@ void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) while (--num != 0); } -void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) { do { diff --git a/C/Compress/Lz/MatchFinder.h b/C/LzFind.h index 74f52a8f..01b9f732 100755 --- a/C/Compress/Lz/MatchFinder.h +++ b/C/LzFind.h @@ -1,9 +1,19 @@ -/* MatchFinder.h */ +/* LzFind.h -- Match finder for LZ algorithms +2008-04-04 +Copyright (c) 1999-2008 Igor Pavlov +You can use any of the following license options: + 1) GNU Lesser General Public License (GNU LGPL) + 2) Common Public License (CPL) + 3) Common Development and Distribution License (CDDL) Version 1.0 + 4) Igor Pavlov, as the author of this code, expressly permits you to + statically or dynamically link your code (or bind by name) to this file, + while you keep this file unmodified. +*/ -#ifndef __MATCHFINDER_H -#define __MATCHFINDER_H +#ifndef __LZFIND_H +#define __LZFIND_H -#include "../../IStream.h" +#include "Types.h" typedef UInt32 CLzRef; @@ -41,8 +51,8 @@ typedef struct _CMatchFinder UInt32 fixedHashSize; UInt32 hashSizeSum; UInt32 numSons; - - HRes result; + SRes result; + UInt32 crc[256]; } CMatchFinder; #define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) diff --git a/C/Compress/Lz/MatchFinderMt.c b/C/LzFindMt.c index ea65a6e6..7ed2030a 100755 --- a/C/Compress/Lz/MatchFinderMt.c +++ b/C/LzFindMt.c @@ -1,21 +1,11 @@ -/* MatchFinderMt.c */ +/* LzFindMt.c -- multithreaded Match finder for LZ algorithms +2008-04-11 +Copyright (c) 1999-2008 Igor Pavlov +Read LzFind.h for license options */ -#ifdef _WIN32 -#define USE_ALLOCA -#endif - -#ifdef USE_ALLOCA -#ifdef _WIN32 -#include <malloc.h> -#else -#include <stdlib.h> -#endif -#endif - -#include "../../7zCrc.h" #include "LzHash.h" -#include "MatchFinderMt.h" +#include "LzFindMt.h" void MtSync_Construct(CMtSync *p) { @@ -107,52 +97,55 @@ void MtSync_Destruct(CMtSync *p) p->wasCreated = False; } -HRes MtSync_Create2(CMtSync *p, unsigned (StdCall *startAddress)(void *), void *obj, UInt32 numBlocks) +#define RINOK_THREAD(x) { if((x) != 0) return SZ_ERROR_THREAD; } + +static SRes MtSync_Create2(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks) { if (p->wasCreated) return SZ_OK; - RINOK(CriticalSection_Init(&p->cs)); + RINOK_THREAD(CriticalSection_Init(&p->cs)); p->csWasInitialized = True; - RINOK(AutoResetEvent_CreateNotSignaled(&p->canStart)); - RINOK(AutoResetEvent_CreateNotSignaled(&p->wasStarted)); - RINOK(AutoResetEvent_CreateNotSignaled(&p->wasStopped)); + RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canStart)); + RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStarted)); + RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStopped)); - RINOK(Semaphore_Create(&p->freeSemaphore, numBlocks, numBlocks)); - RINOK(Semaphore_Create(&p->filledSemaphore, 0, numBlocks)); + RINOK_THREAD(Semaphore_Create(&p->freeSemaphore, numBlocks, numBlocks)); + RINOK_THREAD(Semaphore_Create(&p->filledSemaphore, 0, numBlocks)); p->needStart = True; - RINOK(Thread_Create(&p->thread, startAddress, obj)); + RINOK_THREAD(Thread_Create(&p->thread, startAddress, obj)); p->wasCreated = True; return SZ_OK; } -HRes MtSync_Create(CMtSync *p, unsigned (StdCall *startAddress)(void *), void *obj, UInt32 numBlocks) +static SRes MtSync_Create(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks) { - HRes res = MtSync_Create2(p, startAddress, obj, numBlocks); + SRes res = MtSync_Create2(p, startAddress, obj, numBlocks); if (res != SZ_OK) MtSync_Destruct(p); return res; } - void MtSync_Init(CMtSync *p) { p->needStart = True; } #define kMtMaxValForNormalize 0xFFFFFFFF -#define DEF_GetHeads(name, v) \ +#define DEF_GetHeads2(name, v, action) \ static void GetHeads ## name(const Byte *p, UInt32 pos, \ -UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads) { \ -for (; numHeads != 0; numHeads--) { \ +UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \ +{ action; for (; numHeads != 0; numHeads--) { \ const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++; } } -DEF_GetHeads(2, (p[0] | ((UInt32)p[1] << 8)) & hashMask) -DEF_GetHeads(3, (g_CrcTable[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask) -DEF_GetHeads(4, (g_CrcTable[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (g_CrcTable[p[3]] << 5)) & hashMask) -DEF_GetHeads(4b, (g_CrcTable[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask) -DEF_GetHeads(5, (g_CrcTable[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (g_CrcTable[p[3]] << 5) ^ (g_CrcTable[p[4]] << 3)) & hashMask) +#define DEF_GetHeads(name, v) DEF_GetHeads2(name, v, ;) + +DEF_GetHeads2(2, (p[0] | ((UInt32)p[1] << 8)), hashMask = hashMask; crc = crc; ) +DEF_GetHeads(3, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask) +DEF_GetHeads(4, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5)) & hashMask) +DEF_GetHeads(4b, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask) +DEF_GetHeads(5, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5) ^ (crc[p[4]] << 3)) & hashMask) void HashThreadFunc(CMatchFinderMt *mt) { @@ -211,7 +204,7 @@ void HashThreadFunc(CMatchFinderMt *mt) num = num - mf->numHashBytes + 1; if (num > kMtHashBlockSize - 2) num = kMtHashBlockSize - 2; - mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num); + mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num, mf->crc); heads[0] += num; } mf->pos += num; @@ -238,13 +231,7 @@ void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p) #ifdef MFMT_GM_INLINE -#if _MSC_VER >= 1300 -#define NO_INLINE __declspec(noinline) __fastcall -#else -#ifdef _MSC_VER -#define NO_INLINE __fastcall -#endif -#endif +#define NO_INLINE MY_FAST_CALL Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son, UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, @@ -452,7 +439,7 @@ void MatchFinderMt_Construct(CMatchFinderMt *p) void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc) { - alloc->Free(p->hashBuf); + alloc->Free(alloc, p->hashBuf); p->hashBuf = 0; } @@ -466,34 +453,35 @@ void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc) #define kHashBufferSize (kMtHashBlockSize * kMtHashNumBlocks) #define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks) -static unsigned StdCall HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; } -static unsigned StdCall BtThreadFunc2(void *p) +static unsigned MY_STD_CALL HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; } +static unsigned MY_STD_CALL BtThreadFunc2(void *p) { - #ifdef USE_ALLOCA - alloca(0x180); - #endif + Byte allocaDummy[0x180]; + int i = 0; + for (i = 0; i < 16; i++) + allocaDummy[i] = (Byte)i; BtThreadFunc((CMatchFinderMt *)p); return 0; } -HRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore, +SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc) { CMatchFinder *mf = p->MatchFinder; p->historySize = historySize; if (kMtBtBlockSize <= matchMaxLen * 4) - return E_INVALIDARG; + return SZ_ERROR_PARAM; if (p->hashBuf == 0) { - p->hashBuf = (UInt32 *)alloc->Alloc((kHashBufferSize + kBtBufferSize) * sizeof(UInt32)); + p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32)); if (p->hashBuf == 0) - return SZE_OUTOFMEMORY; + return SZ_ERROR_MEM; p->btBuf = p->hashBuf + kHashBufferSize; } keepAddBufferBefore += (kHashBufferSize + kBtBufferSize); keepAddBufferAfter += kMtHashBlockSize; if (!MatchFinder_Create(mf, historySize, keepAddBufferBefore, matchMaxLen, keepAddBufferAfter, alloc)) - return SZE_OUTOFMEMORY; + return SZ_ERROR_MEM; RINOK(MtSync_Create(&p->hashSync, HashThreadFunc2, p, kMtHashNumBlocks)); RINOK(MtSync_Create(&p->btSync, BtThreadFunc2, p, kMtBtNumBlocks)); @@ -513,6 +501,7 @@ void MatchFinderMt_Init(CMatchFinderMt *p) p->hash = mf->hash; p->fixedHashSize = mf->fixedHashSize; + p->crc = mf->crc; p->son = mf->son; p->matchMaxLen = mf->matchMaxLen; diff --git a/C/Compress/Lz/MatchFinderMt.h b/C/LzFindMt.h index e718a09e..36343b4f 100755 --- a/C/Compress/Lz/MatchFinderMt.h +++ b/C/LzFindMt.h @@ -1,10 +1,13 @@ -/* MatchFinderMt.h */ +/* LzFindMt.h -- multithreaded Match finder for LZ algorithms +2008-04-04 +Copyright (c) 1999-2008 Igor Pavlov +Read LzFind.h for license options */ -#ifndef __MATCHFINDERMT_H -#define __MATCHFINDERMT_H +#ifndef __LZFINDMT_H +#define __LZFINDMT_H -#include "../../Threads.h" -#include "MatchFinder.h" +#include "Threads.h" +#include "LzFind.h" #define kMtHashBlockSize (1 << 13) #define kMtHashNumBlocks (1 << 3) @@ -39,7 +42,7 @@ typedef UInt32 * (*Mf_Mix_Matches)(void *p, UInt32 matchMinPos, UInt32 *distance #define kMtCacheLineDummy 128 typedef void (*Mf_GetHeads)(const Byte *buffer, UInt32 pos, - UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads); + UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc); typedef struct _CMatchFinderMt { @@ -54,6 +57,7 @@ typedef struct _CMatchFinderMt UInt32 *hash; UInt32 fixedHashSize; UInt32 historySize; + const UInt32 *crc; Mf_Mix_Matches MixMatchesFunc; @@ -87,7 +91,7 @@ typedef struct _CMatchFinderMt void MatchFinderMt_Construct(CMatchFinderMt *p); void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc); -HRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore, +SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc); void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable); void MatchFinderMt_ReleaseStream(CMatchFinderMt *p); diff --git a/C/Compress/Lz/LzHash.h b/C/LzHash.h index 87c28365..9a7a2020 100755 --- a/C/Compress/Lz/LzHash.h +++ b/C/LzHash.h @@ -1,7 +1,10 @@ -/* LzHash.h */ +/* LzHash.h -- HASH functions for LZ algorithms +2008-03-26 +Copyright (c) 1999-2008 Igor Pavlov +Read LzFind.h for license options */ -#ifndef __C_LZHASH_H -#define __C_LZHASH_H +#ifndef __LZHASH_H +#define __LZHASH_H #define kHash2Size (1 << 10) #define kHash3Size (1 << 16) @@ -14,40 +17,40 @@ #define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8); #define HASH3_CALC { \ - UInt32 temp = g_CrcTable[cur[0]] ^ cur[1]; \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ hash2Value = temp & (kHash2Size - 1); \ hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } #define HASH4_CALC { \ - UInt32 temp = g_CrcTable[cur[0]] ^ cur[1]; \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ hash2Value = temp & (kHash2Size - 1); \ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ - hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (g_CrcTable[cur[3]] << 5)) & p->hashMask; } + hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; } #define HASH5_CALC { \ - UInt32 temp = g_CrcTable[cur[0]] ^ cur[1]; \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ hash2Value = temp & (kHash2Size - 1); \ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ - hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (g_CrcTable[cur[3]] << 5)); \ - hashValue = (hash4Value ^ (g_CrcTable[cur[4]] << 3)) & p->hashMask; \ + hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \ + hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \ hash4Value &= (kHash4Size - 1); } -/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ g_CrcTable[cur[2]]) & 0xFFFF; */ -#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ g_CrcTable[cur[1]]) & 0xFFFF; +/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */ +#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; #define MT_HASH2_CALC \ - hash2Value = (g_CrcTable[cur[0]] ^ cur[1]) & (kHash2Size - 1); + hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1); #define MT_HASH3_CALC { \ - UInt32 temp = g_CrcTable[cur[0]] ^ cur[1]; \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ hash2Value = temp & (kHash2Size - 1); \ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } #define MT_HASH4_CALC { \ - UInt32 temp = g_CrcTable[cur[0]] ^ cur[1]; \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ hash2Value = temp & (kHash2Size - 1); \ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ - hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (g_CrcTable[cur[3]] << 5)) & (kHash4Size - 1); } + hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); } #endif diff --git a/C/LzmaDec.c b/C/LzmaDec.c new file mode 100755 index 00000000..37dd6c9d --- /dev/null +++ b/C/LzmaDec.c @@ -0,0 +1,1014 @@ +/* LzmaDec.c -- LZMA Decoder +2008-04-29 +Copyright (c) 1999-2008 Igor Pavlov +Read LzmaDec.h for license options */ + +#include "LzmaDec.h" + +#include <string.h> + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +#define RC_INIT_SIZE 5 + +#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } + +#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) +#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); +#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); +#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ + { UPDATE_0(p); i = (i + i); A0; } else \ + { UPDATE_1(p); i = (i + i) + 1; A1; } +#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) + +#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } +#define TREE_DECODE(probs, limit, i) \ + { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } + +/* #define _LZMA_SIZE_OPT */ + +#ifdef _LZMA_SIZE_OPT +#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) +#else +#define TREE_6_DECODE(probs, i) \ + { i = 1; \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + i -= 0x40; } +#endif + +#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } + +#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) +#define UPDATE_0_CHECK range = bound; +#define UPDATE_1_CHECK range -= bound; code -= bound; +#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ + { UPDATE_0_CHECK; i = (i + i); A0; } else \ + { UPDATE_1_CHECK; i = (i + i) + 1; A1; } +#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) +#define TREE_DECODE_CHECK(probs, limit, i) \ + { i = 1; do { GET_BIT_CHECK(probs + i, i) } while(i < limit); i -= limit; } + + +#define kNumPosBitsMax 4 +#define kNumPosStatesMax (1 << kNumPosBitsMax) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define LenChoice 0 +#define LenChoice2 (LenChoice + 1) +#define LenLow (LenChoice2 + 1) +#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) +#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) +#define kNumLenProbs (LenHigh + kLenNumHighSymbols) + + +#define kNumStates 12 +#define kNumLitStates 7 + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#define kNumPosSlotBits 6 +#define kNumLenToPosStates 4 + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) + +#define kMatchMinLen 2 +#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) + +#define IsMatch 0 +#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) +#define IsRepG0 (IsRep + kNumStates) +#define IsRepG1 (IsRepG0 + kNumStates) +#define IsRepG2 (IsRepG1 + kNumStates) +#define IsRep0Long (IsRepG2 + kNumStates) +#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) +#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) +#define LenCoder (Align + kAlignTableSize) +#define RepLenCoder (LenCoder + kNumLenProbs) +#define Literal (RepLenCoder + kNumLenProbs) + +#define LZMA_BASE_SIZE 1846 +#define LZMA_LIT_SIZE 768 + +#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) + +#if Literal != LZMA_BASE_SIZE +StopCompilingDueBUG +#endif + +/* +#define LZMA_STREAM_WAS_FINISHED_ID (-1) +#define LZMA_SPEC_LEN_OFFSET (-3) +*/ + +Byte kLiteralNextStates[kNumStates * 2] = +{ + 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5, + 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10 +}; + +#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 +Out: + Result: + 0 - OK + 1 - Error + p->remainLen: + < kMatchSpecLenStart : normal remain + = kMatchSpecLenStart : finished + = kMatchSpecLenStart + 1 : Flush marker + = kMatchSpecLenStart + 2 : State Init Marker +*/ + +static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) +{ + CLzmaProb *probs = p->probs; + + unsigned state = p->state; + UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; + unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; + unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; + unsigned lc = p->prop.lc; + + Byte *dic = p->dic; + SizeT dicBufSize = p->dicBufSize; + SizeT dicPos = p->dicPos; + + UInt32 processedPos = p->processedPos; + UInt32 checkDicSize = p->checkDicSize; + unsigned len = 0; + + const Byte *buf = p->buf; + UInt32 range = p->range; + UInt32 code = p->code; + + do + { + CLzmaProb *prob; + UInt32 bound; + unsigned ttt; + unsigned posState = processedPos & pbMask; + + prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; + IF_BIT_0(prob) + { + unsigned symbol; + UPDATE_0(prob); + prob = probs + Literal; + if (checkDicSize != 0 || processedPos != 0) + prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + + (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); + + if (state < kNumLitStates) + { + symbol = 1; + do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); + } + else + { + unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; + unsigned offs = 0x100; + symbol = 1; + do + { + unsigned bit; + CLzmaProb *probLit; + matchByte <<= 1; + bit = (matchByte & offs); + probLit = prob + offs + bit + symbol; + GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) + } + while (symbol < 0x100); + } + dic[dicPos++] = (Byte)symbol; + processedPos++; + + state = kLiteralNextStates[state]; + /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */ + continue; + } + else + { + UPDATE_1(prob); + prob = probs + IsRep + state; + IF_BIT_0(prob) + { + UPDATE_0(prob); + state += kNumStates; + prob = probs + LenCoder; + } + else + { + UPDATE_1(prob); + if (checkDicSize == 0 && processedPos == 0) + return SZ_ERROR_DATA; + prob = probs + IsRepG0 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob); + prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; + IF_BIT_0(prob) + { + UPDATE_0(prob); + dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; + dicPos++; + processedPos++; + state = state < kNumLitStates ? 9 : 11; + continue; + } + UPDATE_1(prob); + } + else + { + UInt32 distance; + UPDATE_1(prob); + prob = probs + IsRepG1 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob); + distance = rep1; + } + else + { + UPDATE_1(prob); + prob = probs + IsRepG2 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob); + distance = rep2; + } + else + { + UPDATE_1(prob); + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + state = state < kNumLitStates ? 8 : 11; + prob = probs + RepLenCoder; + } + { + unsigned limit, offset; + CLzmaProb *probLen = prob + LenChoice; + IF_BIT_0(probLen) + { + UPDATE_0(probLen); + probLen = prob + LenLow + (posState << kLenNumLowBits); + offset = 0; + limit = (1 << kLenNumLowBits); + } + else + { + UPDATE_1(probLen); + probLen = prob + LenChoice2; + IF_BIT_0(probLen) + { + UPDATE_0(probLen); + probLen = prob + LenMid + (posState << kLenNumMidBits); + offset = kLenNumLowSymbols; + limit = (1 << kLenNumMidBits); + } + else + { + UPDATE_1(probLen); + probLen = prob + LenHigh; + offset = kLenNumLowSymbols + kLenNumMidSymbols; + limit = (1 << kLenNumHighBits); + } + } + TREE_DECODE(probLen, limit, len); + len += offset; + } + + if (state >= kNumStates) + { + UInt32 distance; + prob = probs + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); + TREE_6_DECODE(prob, distance); + if (distance >= kStartPosModelIndex) + { + unsigned posSlot = (unsigned)distance; + int numDirectBits = (int)(((distance >> 1) - 1)); + distance = (2 | (distance & 1)); + if (posSlot < kEndPosModelIndex) + { + distance <<= numDirectBits; + prob = probs + SpecPos + distance - posSlot - 1; + { + UInt32 mask = 1; + unsigned i = 1; + do + { + GET_BIT2(prob + i, i, ; , distance |= mask); + mask <<= 1; + } + while(--numDirectBits != 0); + } + } + else + { + numDirectBits -= kNumAlignBits; + do + { + NORMALIZE + range >>= 1; + + { + UInt32 t; + code -= range; + t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ + distance = (distance << 1) + (t + 1); + code += range & t; + } + /* + distance <<= 1; + if (code >= range) + { + code -= range; + distance |= 1; + } + */ + } + while (--numDirectBits != 0); + prob = probs + Align; + distance <<= kNumAlignBits; + { + unsigned i = 1; + GET_BIT2(prob + i, i, ; , distance |= 1); + GET_BIT2(prob + i, i, ; , distance |= 2); + GET_BIT2(prob + i, i, ; , distance |= 4); + GET_BIT2(prob + i, i, ; , distance |= 8); + } + if (distance == (UInt32)0xFFFFFFFF) + { + len += kMatchSpecLenStart; + state -= kNumStates; + break; + } + } + } + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + rep0 = distance + 1; + if (checkDicSize == 0) + { + if (distance >= processedPos) + return SZ_ERROR_DATA; + } + else if (distance >= checkDicSize) + return SZ_ERROR_DATA; + state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; + /* state = kLiteralNextStates[state]; */ + } + + len += kMatchMinLen; + + { + SizeT rem = limit - dicPos; + unsigned curLen = ((rem < len) ? (unsigned)rem : len); + SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); + + processedPos += curLen; + + len -= curLen; + if (pos + curLen <= dicBufSize) + { + Byte *dest = dic + dicPos; + ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; + const Byte *lim = dest + curLen; + dicPos += curLen; + do + *(dest) = (Byte)*(dest + src); + while (++dest != lim); + } + else + { + do + { + dic[dicPos++] = dic[pos]; + if (++pos == dicBufSize) + pos = 0; + } + while (--curLen != 0); + } + } + } + } + while (dicPos < limit && buf < bufLimit); + NORMALIZE; + p->buf = buf; + p->range = range; + p->code = code; + p->remainLen = len; + p->dicPos = dicPos; + p->processedPos = processedPos; + p->reps[0] = rep0; + p->reps[1] = rep1; + p->reps[2] = rep2; + p->reps[3] = rep3; + p->state = state; + + return SZ_OK; +} + +static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) +{ + if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) + { + Byte *dic = p->dic; + SizeT dicPos = p->dicPos; + SizeT dicBufSize = p->dicBufSize; + unsigned len = p->remainLen; + UInt32 rep0 = p->reps[0]; + if (limit - dicPos < len) + len = (unsigned)(limit - dicPos); + + if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) + p->checkDicSize = p->prop.dicSize; + + p->processedPos += len; + p->remainLen -= len; + while (len-- != 0) + { + dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; + dicPos++; + } + p->dicPos = dicPos; + } +} + +/* LzmaDec_DecodeReal2 decodes LZMA-symbols and sets p->needFlush and p->needInit, if required. */ + +static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) +{ + do + { + SizeT limit2 = limit; + if (p->checkDicSize == 0) + { + UInt32 rem = p->prop.dicSize - p->processedPos; + if (limit - p->dicPos > rem) + limit2 = p->dicPos + rem; + } + RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); + if (p->processedPos >= p->prop.dicSize) + p->checkDicSize = p->prop.dicSize; + LzmaDec_WriteRem(p, limit); + } + while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); + + if (p->remainLen > kMatchSpecLenStart) + { + p->remainLen = kMatchSpecLenStart; + } + return 0; +} + +typedef enum +{ + DUMMY_ERROR, /* unexpected end of input stream */ + DUMMY_LIT, + DUMMY_MATCH, + DUMMY_REP +} ELzmaDummy; + +static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) +{ + UInt32 range = p->range; + UInt32 code = p->code; + const Byte *bufLimit = buf + inSize; + CLzmaProb *probs = p->probs; + unsigned state = p->state; + ELzmaDummy res; + + { + CLzmaProb *prob; + UInt32 bound; + unsigned ttt; + unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); + + prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK + + /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ + + prob = probs + Literal; + if (p->checkDicSize != 0 || p->processedPos != 0) + prob += (LZMA_LIT_SIZE * + ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + + (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); + + if (state < kNumLitStates) + { + unsigned symbol = 1; + do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); + } + else + { + unsigned matchByte = p->dic[p->dicPos - p->reps[0] + + ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; + unsigned offs = 0x100; + unsigned symbol = 1; + do + { + unsigned bit; + CLzmaProb *probLit; + matchByte <<= 1; + bit = (matchByte & offs); + probLit = prob + offs + bit + symbol; + GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) + } + while (symbol < 0x100); + } + res = DUMMY_LIT; + } + else + { + unsigned len; + UPDATE_1_CHECK; + + prob = probs + IsRep + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + state = 0; + prob = probs + LenCoder; + res = DUMMY_MATCH; + } + else + { + UPDATE_1_CHECK; + res = DUMMY_REP; + prob = probs + IsRepG0 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + NORMALIZE_CHECK; + return DUMMY_REP; + } + else + { + UPDATE_1_CHECK; + } + } + else + { + UPDATE_1_CHECK; + prob = probs + IsRepG1 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + } + else + { + UPDATE_1_CHECK; + prob = probs + IsRepG2 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + } + else + { + UPDATE_1_CHECK; + } + } + } + state = kNumStates; + prob = probs + RepLenCoder; + } + { + unsigned limit, offset; + CLzmaProb *probLen = prob + LenChoice; + IF_BIT_0_CHECK(probLen) + { + UPDATE_0_CHECK; + probLen = prob + LenLow + (posState << kLenNumLowBits); + offset = 0; + limit = 1 << kLenNumLowBits; + } + else + { + UPDATE_1_CHECK; + probLen = prob + LenChoice2; + IF_BIT_0_CHECK(probLen) + { + UPDATE_0_CHECK; + probLen = prob + LenMid + (posState << kLenNumMidBits); + offset = kLenNumLowSymbols; + limit = 1 << kLenNumMidBits; + } + else + { + UPDATE_1_CHECK; + probLen = prob + LenHigh; + offset = kLenNumLowSymbols + kLenNumMidSymbols; + limit = 1 << kLenNumHighBits; + } + } + TREE_DECODE_CHECK(probLen, limit, len); + len += offset; + } + + if (state < 4) + { + unsigned posSlot; + prob = probs + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << + kNumPosSlotBits); + TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); + if (posSlot >= kStartPosModelIndex) + { + int numDirectBits = ((posSlot >> 1) - 1); + + /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ + + if (posSlot < kEndPosModelIndex) + { + prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; + } + else + { + numDirectBits -= kNumAlignBits; + do + { + NORMALIZE_CHECK + range >>= 1; + code -= range & (((code - range) >> 31) - 1); + /* if (code >= range) code -= range; */ + } + while (--numDirectBits != 0); + prob = probs + Align; + numDirectBits = kNumAlignBits; + } + { + unsigned i = 1; + do + { + GET_BIT_CHECK(prob + i, i); + } + while(--numDirectBits != 0); + } + } + } + } + } + NORMALIZE_CHECK; + return res; +} + + +static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) +{ + p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); + p->range = 0xFFFFFFFF; + p->needFlush = 0; +} + +void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) +{ + p->needFlush = 1; + p->remainLen = 0; + p->tempBufSize = 0; + + if (initDic) + { + p->processedPos = 0; + p->checkDicSize = 0; + p->needInitState = 1; + } + if (initState) + p->needInitState = 1; +} + +void LzmaDec_Init(CLzmaDec *p) +{ + p->dicPos = 0; + LzmaDec_InitDicAndState(p, True, True); +} + +static void LzmaDec_InitStateReal(CLzmaDec *p) +{ + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); + UInt32 i; + CLzmaProb *probs = p->probs; + for (i = 0; i < numProbs; i++) + probs[i] = kBitModelTotal >> 1; + p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; + p->state = 0; + p->needInitState = 0; +} + +SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, + ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT inSize = *srcLen; + (*srcLen) = 0; + LzmaDec_WriteRem(p, dicLimit); + + *status = LZMA_STATUS_NOT_SPECIFIED; + + while (p->remainLen != kMatchSpecLenStart) + { + int checkEndMarkNow; + + if (p->needFlush != 0) + { + 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; + + LzmaDec_InitRc(p, p->tempBuf); + p->tempBufSize = 0; + } + + checkEndMarkNow = 0; + if (p->dicPos >= dicLimit) + { + if (p->remainLen == 0 && p->code == 0) + { + *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; + return SZ_OK; + } + if (finishMode == LZMA_FINISH_ANY) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_OK; + } + if (p->remainLen != 0) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_ERROR_DATA; + } + checkEndMarkNow = 1; + } + + if (p->needInitState) + LzmaDec_InitStateReal(p); + + if (p->tempBufSize == 0) + { + SizeT processed; + const Byte *bufLimit; + if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) + { + int dummyRes = LzmaDec_TryDummy(p, src, inSize); + if (dummyRes == DUMMY_ERROR) + { + memcpy(p->tempBuf, src, inSize); + p->tempBufSize = (unsigned)inSize; + (*srcLen) += inSize; + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + if (checkEndMarkNow && dummyRes != DUMMY_MATCH) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_ERROR_DATA; + } + bufLimit = src; + } + else + bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; + p->buf = src; + if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) + return SZ_ERROR_DATA; + processed = p->buf - src; + (*srcLen) += processed; + src += processed; + inSize -= processed; + } + else + { + unsigned rem = p->tempBufSize, lookAhead = 0; + while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) + p->tempBuf[rem++] = src[lookAhead++]; + p->tempBufSize = rem; + if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) + { + int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); + if (dummyRes == DUMMY_ERROR) + { + (*srcLen) += lookAhead; + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + if (checkEndMarkNow && dummyRes != DUMMY_MATCH) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_ERROR_DATA; + } + } + p->buf = p->tempBuf; + if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) + return SZ_ERROR_DATA; + lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); + (*srcLen) += lookAhead; + src += lookAhead; + inSize -= lookAhead; + p->tempBufSize = 0; + } + } + if (p->code == 0) + *status = LZMA_STATUS_FINISHED_WITH_MARK; + return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; +} + +SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT outSize = *destLen; + SizeT inSize = *srcLen; + *srcLen = *destLen = 0; + for (;;) + { + SizeT inSizeCur = inSize, outSizeCur, dicPos; + ELzmaFinishMode curFinishMode; + SRes res; + if (p->dicPos == p->dicBufSize) + p->dicPos = 0; + dicPos = p->dicPos; + if (outSize > p->dicBufSize - dicPos) + { + outSizeCur = p->dicBufSize; + curFinishMode = LZMA_FINISH_ANY; + } + else + { + outSizeCur = dicPos + outSize; + curFinishMode = finishMode; + } + + res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); + src += inSizeCur; + inSize -= inSizeCur; + *srcLen += inSizeCur; + outSizeCur = p->dicPos - dicPos; + memcpy(dest, p->dic + dicPos, outSizeCur); + dest += outSizeCur; + outSize -= outSizeCur; + *destLen += outSizeCur; + if (res != 0) + return res; + if (outSizeCur == 0 || outSize == 0) + return SZ_OK; + } +} + +void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->probs); + p->probs = 0; +} + +static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->dic); + p->dic = 0; +} + +void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) +{ + LzmaDec_FreeProbs(p, alloc); + LzmaDec_FreeDict(p, alloc); +} + +SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) +{ + UInt32 dicSize; + Byte d; + + if (size < LZMA_PROPS_SIZE) + return SZ_ERROR_UNSUPPORTED; + else + dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); + + if (dicSize < LZMA_DIC_MIN) + dicSize = LZMA_DIC_MIN; + p->dicSize = dicSize; + + d = data[0]; + if (d >= (9 * 5 * 5)) + return SZ_ERROR_UNSUPPORTED; + + p->lc = d % 9; + d /= 9; + p->pb = d / 5; + p->lp = d % 5; + + return SZ_OK; +} + +static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) +{ + UInt32 numProbs = LzmaProps_GetNumProbs(propNew); + if (p->probs == 0 || numProbs != p->numProbs) + { + LzmaDec_FreeProbs(p, alloc); + p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); + p->numProbs = numProbs; + if (p->probs == 0) + return SZ_ERROR_MEM; + } + return SZ_OK; +} + +SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) +{ + CLzmaProps propNew; + RINOK(LzmaProps_Decode(&propNew, props, propsSize)); + RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); + p->prop = propNew; + return SZ_OK; +} + +SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) +{ + CLzmaProps propNew; + SizeT dicBufSize; + RINOK(LzmaProps_Decode(&propNew, props, propsSize)); + RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); + dicBufSize = propNew.dicSize; + if (p->dic == 0 || dicBufSize != p->dicBufSize) + { + LzmaDec_FreeDict(p, alloc); + p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); + if (p->dic == 0) + { + LzmaDec_FreeProbs(p, alloc); + return SZ_ERROR_MEM; + } + } + p->dicBufSize = dicBufSize; + p->prop = propNew; + return SZ_OK; +} + +SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, + ELzmaStatus *status, ISzAlloc *alloc) +{ + CLzmaDec p; + SRes res; + SizeT inSize = *srcLen; + SizeT outSize = *destLen; + *srcLen = *destLen = 0; + if (inSize < RC_INIT_SIZE) + return SZ_ERROR_INPUT_EOF; + + LzmaDec_Construct(&p); + res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); + if (res != 0) + return res; + p.dic = dest; + p.dicBufSize = outSize; + + LzmaDec_Init(&p); + + *srcLen = inSize; + res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); + + if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) + res = SZ_ERROR_INPUT_EOF; + + (*destLen) = p.dicPos; + LzmaDec_FreeProbs(&p, alloc); + return res; +} diff --git a/C/LzmaDec.h b/C/LzmaDec.h new file mode 100755 index 00000000..9610f0ec --- /dev/null +++ b/C/LzmaDec.h @@ -0,0 +1,232 @@ +/* LzmaDec.h -- LZMA Decoder +2008-04-29 +Copyright (c) 1999-2008 Igor Pavlov +You can use any of the following license options: + 1) GNU Lesser General Public License (GNU LGPL) + 2) Common Public License (CPL) + 3) Common Development and Distribution License (CDDL) Version 1.0 + 4) Igor Pavlov, as the author of this code, expressly permits you to + statically or dynamically link your code (or bind by name) to this file, + while you keep this file unmodified. +*/ + +#ifndef __LZMADEC_H +#define __LZMADEC_H + +#include "Types.h" + +/* #define _LZMA_PROB32 */ +/* _LZMA_PROB32 can increase the speed on some CPUs, + but memory usage for CLzmaDec::probs will be doubled in that case */ + +#ifdef _LZMA_PROB32 +#define CLzmaProb UInt32 +#else +#define CLzmaProb UInt16 +#endif + + +/* ---------- LZMA Properties ---------- */ + +#define LZMA_PROPS_SIZE 5 + +typedef struct _CLzmaProps +{ + unsigned lc, lp, pb; + UInt32 dicSize; +} CLzmaProps; + +/* LzmaProps_Decode - decodes properties +Returns: + SZ_OK + SZ_ERROR_UNSUPPORTED - Unsupported properties +*/ + +SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); + + +/* ---------- LZMA Decoder state ---------- */ + +/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. + Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ + +#define LZMA_REQUIRED_INPUT_MAX 20 + +typedef struct +{ + CLzmaProps prop; + CLzmaProb *probs; + Byte *dic; + const Byte *buf; + UInt32 range, code; + SizeT dicPos; + SizeT dicBufSize; + UInt32 processedPos; + UInt32 checkDicSize; + unsigned state; + UInt32 reps[4]; + unsigned remainLen; + int needFlush; + int needInitState; + UInt32 numProbs; + unsigned tempBufSize; + Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; +} CLzmaDec; + +#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } + +void LzmaDec_Init(CLzmaDec *p); + +/* There are two types of LZMA streams: + 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. + 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ + +typedef enum +{ + LZMA_FINISH_ANY, /* finish at any point */ + LZMA_FINISH_END /* block must be finished at the end */ +} ELzmaFinishMode; + +/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! + + You must use LZMA_FINISH_END, when you know that current output buffer + covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. + + If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, + and output value of destLen will be less than output buffer size limit. + You can check status result also. + + You can use multiple checks to test data integrity after full decompression: + 1) Check Result and "status" variable. + 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. + 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. + You must use correct finish mode in that case. */ + +typedef enum +{ + LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ + LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ + LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ + LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ +} ELzmaStatus; + +/* ELzmaStatus is used only as output value for function call */ + + +/* ---------- Interfaces ---------- */ + +/* There are 3 levels of interfaces: + 1) Dictionary Interface + 2) Buffer Interface + 3) One Call Interface + You can select any of these interfaces, but don't mix functions from different + groups for same object. */ + + +/* There are two variants to allocate state for Dictionary Interface: + 1) LzmaDec_Allocate / LzmaDec_Free + 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs + You can use variant 2, if you set dictionary buffer manually. + For Buffer Interface you must always use variant 1. + +LzmaDec_Allocate* can return: + SZ_OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported properties +*/ + +SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); +void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); + +SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); +void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); + +/* ---------- Dictionary Interface ---------- */ + +/* You can use it, if you want to eliminate the overhead for data copying from + dictionary to some other external buffer. + You must work with CLzmaDec variables directly in this interface. + + STEPS: + LzmaDec_Constr() + LzmaDec_Allocate() + for (each new stream) + { + LzmaDec_Init() + while (it needs more decompression) + { + LzmaDec_DecodeToDic() + use data from CLzmaDec::dic and update CLzmaDec::dicPos + } + } + LzmaDec_Free() +*/ + +/* LzmaDec_DecodeToDic + + The decoding to internal dictionary buffer (CLzmaDec::dic). + You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! + +finishMode: + It has meaning only if the decoding reaches output limit (dicLimit). + LZMA_FINISH_ANY - Decode just dicLimit bytes. + LZMA_FINISH_END - Stream must be finished after dicLimit. + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + LZMA_STATUS_NEEDS_MORE_INPUT + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + SZ_ERROR_DATA - Data error +*/ + +SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + + +/* ---------- Buffer Interface ---------- */ + +/* It's zlib-like interface. + See LzmaDec_DecodeToDic description for information about STEPS and return results, + but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need + to work with CLzmaDec variables manually. + +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + LZMA_FINISH_ANY - Decode just destLen bytes. + LZMA_FINISH_END - Stream must be finished after (*destLen). +*/ + +SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + + +/* ---------- One Call Interface ---------- */ + +/* LzmaDecode + +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + LZMA_FINISH_ANY - Decode just destLen bytes. + LZMA_FINISH_END - Stream must be finished after (*destLen). + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + SZ_ERROR_DATA - Data error + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported properties + SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). +*/ + +SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, + ELzmaStatus *status, ISzAlloc *alloc); + +#endif diff --git a/C/LzmaEnc.c b/C/LzmaEnc.c new file mode 100755 index 00000000..402e2742 --- /dev/null +++ b/C/LzmaEnc.c @@ -0,0 +1,2332 @@ +/* LzmaEnc.c -- LZMA Encoder +2008-04-28 +Copyright (c) 1999-2008 Igor Pavlov +Read LzmaEnc.h for license options */ + +#include <stdio.h> +#include <string.h> + +#include "LzmaEnc.h" + +#include "LzFind.h" +#ifdef COMPRESS_MF_MT +#include "LzFindMt.h" +#endif + +/* #define SHOW_STAT */ +/* #define SHOW_STAT2 */ + +#ifdef SHOW_STAT +static int ttt = 0; +#endif + +#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1) + +#define kBlockSize (9 << 10) +#define kUnpackBlockSize (1 << 18) +#define kMatchArraySize (1 << 21) +#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX) + +#define kNumMaxDirectBits (31) + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 +#define kProbInitValue (kBitModelTotal >> 1) + +#define kNumMoveReducingBits 4 +#define kNumBitPriceShiftBits 4 +#define kBitPrice (1 << kNumBitPriceShiftBits) + +void LzmaEncProps_Init(CLzmaEncProps *p) +{ + p->level = 5; + p->dictSize = p->mc = 0; + p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; + p->writeEndMark = 0; +} + +void LzmaEncProps_Normalize(CLzmaEncProps *p) +{ + int level = p->level; + if (level < 0) level = 5; + p->level = level; + if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26))); + if (p->lc < 0) p->lc = 3; + if (p->lp < 0) p->lp = 0; + if (p->pb < 0) p->pb = 2; + if (p->algo < 0) p->algo = (level < 5 ? 0 : 1); + if (p->fb < 0) p->fb = (level < 7 ? 32 : 64); + if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); + if (p->numHashBytes < 0) p->numHashBytes = 4; + if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1); + if (p->numThreads < 0) p->numThreads = ((p->btMode && p->algo) ? 2 : 1); +} + +UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) +{ + CLzmaEncProps props = *props2; + LzmaEncProps_Normalize(&props); + return props.dictSize; +} + +/* #define LZMA_LOG_BSR */ +/* Define it for Intel's CPU */ + + +#ifdef LZMA_LOG_BSR + +#define kDicLogSizeMaxCompress 30 + +#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); } + +UInt32 GetPosSlot1(UInt32 pos) +{ + UInt32 res; + BSR2_RET(pos, res); + return res; +} +#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } +#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); } + +#else + +#define kNumLogBits (9 + (int)sizeof(size_t) / 2) +#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) + +void LzmaEnc_FastPosInit(Byte *g_FastPos) +{ + int c = 2, slotFast; + g_FastPos[0] = 0; + g_FastPos[1] = 1; + + for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++) + { + UInt32 k = (1 << ((slotFast >> 1) - 1)); + UInt32 j; + for (j = 0; j < k; j++, c++) + g_FastPos[c] = (Byte)slotFast; + } +} + +#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ + (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ + res = p->g_FastPos[pos >> i] + (i * 2); } +/* +#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ + p->g_FastPos[pos >> 6] + 12 : \ + p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; } +*/ + +#define GetPosSlot1(pos) p->g_FastPos[pos] +#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } +#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); } + +#endif + + +#define LZMA_NUM_REPS 4 + +typedef unsigned CState; + +typedef struct _COptimal +{ + UInt32 price; + + CState state; + int prev1IsChar; + int prev2; + + UInt32 posPrev2; + UInt32 backPrev2; + + UInt32 posPrev; + UInt32 backPrev; + UInt32 backs[LZMA_NUM_REPS]; +} COptimal; + +#define kNumOpts (1 << 12) + +#define kNumLenToPosStates 4 +#define kNumPosSlotBits 6 +#define kDicLogSizeMin 0 +#define kDicLogSizeMax 32 +#define kDistTableSizeMax (kDicLogSizeMax * 2) + + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) +#define kAlignMask (kAlignTableSize - 1) + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex) + +#define kNumFullDistances (1 << (kEndPosModelIndex / 2)) + +#ifdef _LZMA_PROB32 +#define CLzmaProb UInt32 +#else +#define CLzmaProb UInt16 +#endif + +#define LZMA_PB_MAX 4 +#define LZMA_LC_MAX 8 +#define LZMA_LP_MAX 4 + +#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX) + + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) + +#define LZMA_MATCH_LEN_MIN 2 +#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1) + +#define kNumStates 12 + +typedef struct +{ + CLzmaProb choice; + CLzmaProb choice2; + CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits]; + CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits]; + CLzmaProb high[kLenNumHighSymbols]; +} CLenEnc; + +typedef struct +{ + CLenEnc p; + UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal]; + UInt32 tableSize; + UInt32 counters[LZMA_NUM_PB_STATES_MAX]; +} CLenPriceEnc; + +typedef struct _CRangeEnc +{ + UInt32 range; + Byte cache; + UInt64 low; + UInt64 cacheSize; + Byte *buf; + Byte *bufLim; + Byte *bufBase; + ISeqOutStream *outStream; + UInt64 processed; + SRes res; +} CRangeEnc; + +typedef struct _CSeqInStreamBuf +{ + ISeqInStream funcTable; + const Byte *data; + SizeT rem; +} CSeqInStreamBuf; + +static SRes MyRead(void *pp, void *data, size_t *size) +{ + size_t curSize = *size; + CSeqInStreamBuf *p = (CSeqInStreamBuf *)pp; + if (p->rem < curSize) + curSize = p->rem; + memcpy(data, p->data, curSize); + p->rem -= curSize; + p->data += curSize; + *size = curSize; + return SZ_OK; +} + +typedef struct +{ + CLzmaProb *litProbs; + + CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; + CLzmaProb isRep[kNumStates]; + CLzmaProb isRepG0[kNumStates]; + CLzmaProb isRepG1[kNumStates]; + CLzmaProb isRepG2[kNumStates]; + CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; + + CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; + CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; + CLzmaProb posAlignEncoder[1 << kNumAlignBits]; + + CLenPriceEnc lenEnc; + CLenPriceEnc repLenEnc; + + UInt32 reps[LZMA_NUM_REPS]; + UInt32 state; +} CSaveState; + +typedef struct _CLzmaEnc +{ + IMatchFinder matchFinder; + void *matchFinderObj; + + #ifdef COMPRESS_MF_MT + Bool mtMode; + CMatchFinderMt matchFinderMt; + #endif + + CMatchFinder matchFinderBase; + + #ifdef COMPRESS_MF_MT + Byte pad[128]; + #endif + + UInt32 optimumEndIndex; + UInt32 optimumCurrentIndex; + + Bool longestMatchWasFound; + UInt32 longestMatchLength; + UInt32 numDistancePairs; + + COptimal opt[kNumOpts]; + + #ifndef LZMA_LOG_BSR + Byte g_FastPos[1 << kNumLogBits]; + #endif + + UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; + UInt32 matchDistances[LZMA_MATCH_LEN_MAX * 2 + 2 + 1]; + UInt32 numFastBytes; + UInt32 additionalOffset; + UInt32 reps[LZMA_NUM_REPS]; + UInt32 state; + + UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; + UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances]; + UInt32 alignPrices[kAlignTableSize]; + UInt32 alignPriceCount; + + UInt32 distTableSize; + + unsigned lc, lp, pb; + unsigned lpMask, pbMask; + + CLzmaProb *litProbs; + + CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; + CLzmaProb isRep[kNumStates]; + CLzmaProb isRepG0[kNumStates]; + CLzmaProb isRepG1[kNumStates]; + CLzmaProb isRepG2[kNumStates]; + CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; + + CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; + CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; + CLzmaProb posAlignEncoder[1 << kNumAlignBits]; + + CLenPriceEnc lenEnc; + CLenPriceEnc repLenEnc; + + unsigned lclp; + + Bool fastMode; + + CRangeEnc rc; + + Bool writeEndMark; + UInt64 nowPos64; + UInt32 matchPriceCount; + Bool finished; + Bool multiThread; + + SRes result; + UInt32 dictSize; + UInt32 matchFinderCycles; + + ISeqInStream *inStream; + CSeqInStreamBuf seqBufInStream; + + CSaveState saveState; +} CLzmaEnc; + +void LzmaEnc_SaveState(CLzmaEncHandle pp) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + CSaveState *dest = &p->saveState; + int i; + dest->lenEnc = p->lenEnc; + dest->repLenEnc = p->repLenEnc; + dest->state = p->state; + + for (i = 0; i < kNumStates; i++) + { + memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); + memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); + } + for (i = 0; i < kNumLenToPosStates; i++) + memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); + memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); + memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); + memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); + memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); + memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); + memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); + memcpy(dest->reps, p->reps, sizeof(p->reps)); + memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb)); +} + +void LzmaEnc_RestoreState(CLzmaEncHandle pp) +{ + CLzmaEnc *dest = (CLzmaEnc *)pp; + const CSaveState *p = &dest->saveState; + int i; + dest->lenEnc = p->lenEnc; + dest->repLenEnc = p->repLenEnc; + dest->state = p->state; + + for (i = 0; i < kNumStates; i++) + { + memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); + memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); + } + for (i = 0; i < kNumLenToPosStates; i++) + memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); + memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); + memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); + memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); + memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); + memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); + memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); + memcpy(dest->reps, p->reps, sizeof(p->reps)); + memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb)); +} + +SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + CLzmaEncProps props = *props2; + LzmaEncProps_Normalize(&props); + + if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX || + props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30)) + return SZ_ERROR_PARAM; + p->dictSize = props.dictSize; + p->matchFinderCycles = props.mc; + { + unsigned fb = props.fb; + if (fb < 5) + fb = 5; + if (fb > LZMA_MATCH_LEN_MAX) + fb = LZMA_MATCH_LEN_MAX; + p->numFastBytes = fb; + } + p->lc = props.lc; + p->lp = props.lp; + p->pb = props.pb; + p->fastMode = (props.algo == 0); + p->matchFinderBase.btMode = props.btMode; + { + UInt32 numHashBytes = 4; + if (props.btMode) + { + if (props.numHashBytes < 2) + numHashBytes = 2; + else if (props.numHashBytes < 4) + numHashBytes = props.numHashBytes; + } + p->matchFinderBase.numHashBytes = numHashBytes; + } + + p->matchFinderBase.cutValue = props.mc; + + p->writeEndMark = props.writeEndMark; + + #ifdef COMPRESS_MF_MT + /* + if (newMultiThread != _multiThread) + { + ReleaseMatchFinder(); + _multiThread = newMultiThread; + } + */ + p->multiThread = (props.numThreads > 1); + #endif + + return SZ_OK; +} + +static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; +static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; +static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; +static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; + +/* + void UpdateChar() { Index = kLiteralNextStates[Index]; } + void UpdateMatch() { Index = kMatchNextStates[Index]; } + void UpdateRep() { Index = kRepNextStates[Index]; } + void UpdateShortRep() { Index = kShortRepNextStates[Index]; } +*/ + +#define IsCharState(s) ((s) < 7) + + +#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1) + +#define kInfinityPrice (1 << 30) + +static void RangeEnc_Construct(CRangeEnc *p) +{ + p->outStream = 0; + p->bufBase = 0; +} + +#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize) + +#define RC_BUF_SIZE (1 << 16) +static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) +{ + if (p->bufBase == 0) + { + p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE); + if (p->bufBase == 0) + return 0; + p->bufLim = p->bufBase + RC_BUF_SIZE; + } + return 1; +} + +static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->bufBase); + p->bufBase = 0; +} + +static void RangeEnc_Init(CRangeEnc *p) +{ + /* Stream.Init(); */ + p->low = 0; + p->range = 0xFFFFFFFF; + p->cacheSize = 1; + p->cache = 0; + + p->buf = p->bufBase; + + p->processed = 0; + p->res = SZ_OK; +} + +static void RangeEnc_FlushStream(CRangeEnc *p) +{ + size_t num; + if (p->res != SZ_OK) + return; + num = p->buf - p->bufBase; + if (num != p->outStream->Write(p->outStream, p->bufBase, num)) + p->res = SZ_ERROR_WRITE; + p->processed += num; + p->buf = p->bufBase; +} + +static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p) +{ + if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0) + { + Byte temp = p->cache; + do + { + Byte *buf = p->buf; + *buf++ = (Byte)(temp + (Byte)(p->low >> 32)); + p->buf = buf; + if (buf == p->bufLim) + RangeEnc_FlushStream(p); + temp = 0xFF; + } + while (--p->cacheSize != 0); + p->cache = (Byte)((UInt32)p->low >> 24); + } + p->cacheSize++; + p->low = (UInt32)p->low << 8; +} + +static void RangeEnc_FlushData(CRangeEnc *p) +{ + int i; + for (i = 0; i < 5; i++) + RangeEnc_ShiftLow(p); +} + +static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits) +{ + do + { + p->range >>= 1; + p->low += p->range & (0 - ((value >> --numBits) & 1)); + if (p->range < kTopValue) + { + p->range <<= 8; + RangeEnc_ShiftLow(p); + } + } + while (numBits != 0); +} + +static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol) +{ + UInt32 ttt = *prob; + UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt; + if (symbol == 0) + { + p->range = newBound; + ttt += (kBitModelTotal - ttt) >> kNumMoveBits; + } + else + { + p->low += newBound; + p->range -= newBound; + ttt -= ttt >> kNumMoveBits; + } + *prob = (CLzmaProb)ttt; + if (p->range < kTopValue) + { + p->range <<= 8; + RangeEnc_ShiftLow(p); + } +} + +static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol) +{ + symbol |= 0x100; + do + { + RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1); + symbol <<= 1; + } + while (symbol < 0x10000); +} + +static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte) +{ + UInt32 offs = 0x100; + symbol |= 0x100; + do + { + matchByte <<= 1; + RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1); + symbol <<= 1; + offs &= ~(matchByte ^ symbol); + } + while (symbol < 0x10000); +} + +void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) +{ + UInt32 i; + for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) + { + const int kCyclesBits = kNumBitPriceShiftBits; + UInt32 w = i; + UInt32 bitCount = 0; + int j; + for (j = 0; j < kCyclesBits; j++) + { + w = w * w; + bitCount <<= 1; + while (w >= ((UInt32)1 << 16)) + { + w >>= 1; + bitCount++; + } + } + ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount); + } +} + + +#define GET_PRICE(prob, symbol) \ + p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; + +#define GET_PRICEa(prob, symbol) \ + ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; + +#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits] +#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] + +#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits] +#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] + +static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices) +{ + UInt32 price = 0; + symbol |= 0x100; + do + { + price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1); + symbol <<= 1; + } + while (symbol < 0x10000); + return price; +}; + +static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices) +{ + UInt32 price = 0; + UInt32 offs = 0x100; + symbol |= 0x100; + do + { + matchByte <<= 1; + price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1); + symbol <<= 1; + offs &= ~(matchByte ^ symbol); + } + while (symbol < 0x10000); + return price; +}; + + +static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) +{ + UInt32 m = 1; + int i; + for (i = numBitLevels; i != 0 ;) + { + UInt32 bit; + i--; + bit = (symbol >> i) & 1; + RangeEnc_EncodeBit(rc, probs + m, bit); + m = (m << 1) | bit; + } +}; + +static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) +{ + UInt32 m = 1; + int i; + for (i = 0; i < numBitLevels; i++) + { + UInt32 bit = symbol & 1; + RangeEnc_EncodeBit(rc, probs + m, bit); + m = (m << 1) | bit; + symbol >>= 1; + } +} + +static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) +{ + UInt32 price = 0; + symbol |= (1 << numBitLevels); + while (symbol != 1) + { + price += GET_PRICEa(probs[symbol >> 1], symbol & 1); + symbol >>= 1; + } + return price; +} + +static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) +{ + UInt32 price = 0; + UInt32 m = 1; + int i; + for (i = numBitLevels; i != 0; i--) + { + UInt32 bit = symbol & 1; + symbol >>= 1; + price += GET_PRICEa(probs[m], bit); + m = (m << 1) | bit; + } + return price; +} + + +static void LenEnc_Init(CLenEnc *p) +{ + unsigned i; + p->choice = p->choice2 = kProbInitValue; + for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++) + p->low[i] = kProbInitValue; + for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++) + p->mid[i] = kProbInitValue; + for (i = 0; i < kLenNumHighSymbols; i++) + p->high[i] = kProbInitValue; +} + +static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState) +{ + if (symbol < kLenNumLowSymbols) + { + RangeEnc_EncodeBit(rc, &p->choice, 0); + RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol); + } + else + { + RangeEnc_EncodeBit(rc, &p->choice, 1); + if (symbol < kLenNumLowSymbols + kLenNumMidSymbols) + { + RangeEnc_EncodeBit(rc, &p->choice2, 0); + RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols); + } + else + { + RangeEnc_EncodeBit(rc, &p->choice2, 1); + RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols); + } + } +} + +static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices) +{ + UInt32 a0 = GET_PRICE_0a(p->choice); + UInt32 a1 = GET_PRICE_1a(p->choice); + UInt32 b0 = a1 + GET_PRICE_0a(p->choice2); + UInt32 b1 = a1 + GET_PRICE_1a(p->choice2); + UInt32 i = 0; + for (i = 0; i < kLenNumLowSymbols; i++) + { + if (i >= numSymbols) + return; + prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices); + } + for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++) + { + if (i >= numSymbols) + return; + prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices); + } + for (; i < numSymbols; i++) + prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices); +} + +static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices) +{ + LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices); + p->counters[posState] = p->tableSize; +} + +static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices) +{ + UInt32 posState; + for (posState = 0; posState < numPosStates; posState++) + LenPriceEnc_UpdateTable(p, posState, ProbPrices); +} + +static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices) +{ + LenEnc_Encode(&p->p, rc, symbol, posState); + if (updatePrice) + if (--p->counters[posState] == 0) + LenPriceEnc_UpdateTable(p, posState, ProbPrices); +} + + + + +static void MovePos(CLzmaEnc *p, UInt32 num) +{ + #ifdef SHOW_STAT + ttt += num; + printf("\n MovePos %d", num); + #endif + if (num != 0) + { + p->additionalOffset += num; + p->matchFinder.Skip(p->matchFinderObj, num); + } +} + +static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes) +{ + UInt32 lenRes = 0, numDistancePairs; + numDistancePairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matchDistances); + #ifdef SHOW_STAT + printf("\n i = %d numPairs = %d ", ttt, numDistancePairs / 2); + if (ttt >= 61994) + ttt = ttt; + + ttt++; + { + UInt32 i; + for (i = 0; i < numDistancePairs; i += 2) + printf("%2d %6d | ", p->matchDistances[i], p->matchDistances[i + 1]); + } + #endif + if (numDistancePairs > 0) + { + lenRes = p->matchDistances[numDistancePairs - 2]; + if (lenRes == p->numFastBytes) + { + UInt32 numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) + 1; + const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + UInt32 distance = p->matchDistances[numDistancePairs - 1] + 1; + if (numAvail > LZMA_MATCH_LEN_MAX) + numAvail = LZMA_MATCH_LEN_MAX; + + { + const Byte *pby2 = pby - distance; + for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++); + } + } + } + p->additionalOffset++; + *numDistancePairsRes = numDistancePairs; + return lenRes; +} + + +#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False; +#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False; +#define IsShortRep(p) ((p)->backPrev == 0) + +static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState) +{ + return + GET_PRICE_0(p->isRepG0[state]) + + GET_PRICE_0(p->isRep0Long[state][posState]); +} + +static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState) +{ + UInt32 price; + if (repIndex == 0) + { + price = GET_PRICE_0(p->isRepG0[state]); + price += GET_PRICE_1(p->isRep0Long[state][posState]); + } + else + { + price = GET_PRICE_1(p->isRepG0[state]); + if (repIndex == 1) + price += GET_PRICE_0(p->isRepG1[state]); + else + { + price += GET_PRICE_1(p->isRepG1[state]); + price += GET_PRICE(p->isRepG2[state], repIndex - 2); + } + } + return price; +} + +static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState) +{ + return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] + + GetPureRepPrice(p, repIndex, state, posState); +} + +static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur) +{ + UInt32 posMem = p->opt[cur].posPrev; + UInt32 backMem = p->opt[cur].backPrev; + p->optimumEndIndex = cur; + do + { + if (p->opt[cur].prev1IsChar) + { + MakeAsChar(&p->opt[posMem]) + p->opt[posMem].posPrev = posMem - 1; + if (p->opt[cur].prev2) + { + p->opt[posMem - 1].prev1IsChar = False; + p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2; + p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2; + } + } + { + UInt32 posPrev = posMem; + UInt32 backCur = backMem; + + backMem = p->opt[posPrev].backPrev; + posMem = p->opt[posPrev].posPrev; + + p->opt[posPrev].backPrev = backCur; + p->opt[posPrev].posPrev = cur; + cur = posPrev; + } + } + while (cur != 0); + *backRes = p->opt[0].backPrev; + p->optimumCurrentIndex = p->opt[0].posPrev; + return p->optimumCurrentIndex; +} + +#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300) + +static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) +{ + UInt32 numAvailableBytes, lenMain, numDistancePairs; + const Byte *data; + UInt32 reps[LZMA_NUM_REPS]; + UInt32 repLens[LZMA_NUM_REPS]; + UInt32 repMaxIndex, i; + UInt32 *matchDistances; + Byte currentByte, matchByte; + UInt32 posState; + UInt32 matchPrice, repMatchPrice; + UInt32 lenEnd; + UInt32 len; + UInt32 normalMatchPrice; + UInt32 cur; + if (p->optimumEndIndex != p->optimumCurrentIndex) + { + const COptimal *opt = &p->opt[p->optimumCurrentIndex]; + UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex; + *backRes = opt->backPrev; + p->optimumCurrentIndex = opt->posPrev; + return lenRes; + } + p->optimumCurrentIndex = p->optimumEndIndex = 0; + + numAvailableBytes = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); + + if (!p->longestMatchWasFound) + { + lenMain = ReadMatchDistances(p, &numDistancePairs); + } + else + { + lenMain = p->longestMatchLength; + numDistancePairs = p->numDistancePairs; + p->longestMatchWasFound = False; + } + + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + if (numAvailableBytes < 2) + { + *backRes = (UInt32)(-1); + return 1; + } + if (numAvailableBytes > LZMA_MATCH_LEN_MAX) + numAvailableBytes = LZMA_MATCH_LEN_MAX; + + repMaxIndex = 0; + for (i = 0; i < LZMA_NUM_REPS; i++) + { + UInt32 lenTest; + const Byte *data2; + reps[i] = p->reps[i]; + data2 = data - (reps[i] + 1); + if (data[0] != data2[0] || data[1] != data2[1]) + { + repLens[i] = 0; + continue; + } + for (lenTest = 2; lenTest < numAvailableBytes && data[lenTest] == data2[lenTest]; lenTest++); + repLens[i] = lenTest; + if (lenTest > repLens[repMaxIndex]) + repMaxIndex = i; + } + if (repLens[repMaxIndex] >= p->numFastBytes) + { + UInt32 lenRes; + *backRes = repMaxIndex; + lenRes = repLens[repMaxIndex]; + MovePos(p, lenRes - 1); + return lenRes; + } + + matchDistances = p->matchDistances; + if (lenMain >= p->numFastBytes) + { + *backRes = matchDistances[numDistancePairs - 1] + LZMA_NUM_REPS; + MovePos(p, lenMain - 1); + return lenMain; + } + currentByte = *data; + matchByte = *(data - (reps[0] + 1)); + + if (lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2) + { + *backRes = (UInt32)-1; + return 1; + } + + p->opt[0].state = (CState)p->state; + + posState = (position & p->pbMask); + + { + const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); + p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) + + (!IsCharState(p->state) ? + LitEnc_GetPriceMatched(probs, currentByte, matchByte, p->ProbPrices) : + LitEnc_GetPrice(probs, currentByte, p->ProbPrices)); + } + + MakeAsChar(&p->opt[1]); + + matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]); + repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]); + + if (matchByte == currentByte) + { + UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState); + if (shortRepPrice < p->opt[1].price) + { + p->opt[1].price = shortRepPrice; + MakeAsShortRep(&p->opt[1]); + } + } + lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]); + + if (lenEnd < 2) + { + *backRes = p->opt[1].backPrev; + return 1; + } + + p->opt[1].posPrev = 0; + for (i = 0; i < LZMA_NUM_REPS; i++) + p->opt[0].backs[i] = reps[i]; + + len = lenEnd; + do + p->opt[len--].price = kInfinityPrice; + while (len >= 2); + + for (i = 0; i < LZMA_NUM_REPS; i++) + { + UInt32 repLen = repLens[i]; + UInt32 price; + if (repLen < 2) + continue; + price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState); + do + { + UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2]; + COptimal *opt = &p->opt[repLen]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = 0; + opt->backPrev = i; + opt->prev1IsChar = False; + } + } + while (--repLen >= 2); + } + + normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]); + + len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); + if (len <= lenMain) + { + UInt32 offs = 0; + while (len > matchDistances[offs]) + offs += 2; + for (; ; len++) + { + COptimal *opt; + UInt32 distance = matchDistances[offs + 1]; + + UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN]; + UInt32 lenToPosState = GetLenToPosState(len); + if (distance < kNumFullDistances) + curAndLenPrice += p->distancesPrices[lenToPosState][distance]; + else + { + UInt32 slot; + GetPosSlot2(distance, slot); + curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot]; + } + opt = &p->opt[len]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = 0; + opt->backPrev = distance + LZMA_NUM_REPS; + opt->prev1IsChar = False; + } + if (len == matchDistances[offs]) + { + offs += 2; + if (offs == numDistancePairs) + break; + } + } + } + + cur = 0; + + #ifdef SHOW_STAT2 + if (position >= 0) + { + unsigned i; + printf("\n pos = %4X", position); + for (i = cur; i <= lenEnd; i++) + printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price); + } + #endif + + for (;;) + { + UInt32 numAvailableBytesFull, newLen, numDistancePairs; + COptimal *curOpt; + UInt32 posPrev; + UInt32 state; + UInt32 curPrice; + Bool nextIsChar; + const Byte *data; + Byte currentByte, matchByte; + UInt32 posState; + UInt32 curAnd1Price; + COptimal *nextOpt; + UInt32 matchPrice, repMatchPrice; + UInt32 numAvailableBytes; + UInt32 startLen; + + cur++; + if (cur == lenEnd) + return Backward(p, backRes, cur); + + numAvailableBytesFull = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); + newLen = ReadMatchDistances(p, &numDistancePairs); + if (newLen >= p->numFastBytes) + { + p->numDistancePairs = numDistancePairs; + p->longestMatchLength = newLen; + p->longestMatchWasFound = True; + return Backward(p, backRes, cur); + } + position++; + curOpt = &p->opt[cur]; + posPrev = curOpt->posPrev; + if (curOpt->prev1IsChar) + { + posPrev--; + if (curOpt->prev2) + { + state = p->opt[curOpt->posPrev2].state; + if (curOpt->backPrev2 < LZMA_NUM_REPS) + state = kRepNextStates[state]; + else + state = kMatchNextStates[state]; + } + else + state = p->opt[posPrev].state; + state = kLiteralNextStates[state]; + } + else + state = p->opt[posPrev].state; + if (posPrev == cur - 1) + { + if (IsShortRep(curOpt)) + state = kShortRepNextStates[state]; + else + state = kLiteralNextStates[state]; + } + else + { + UInt32 pos; + const COptimal *prevOpt; + if (curOpt->prev1IsChar && curOpt->prev2) + { + posPrev = curOpt->posPrev2; + pos = curOpt->backPrev2; + state = kRepNextStates[state]; + } + else + { + pos = curOpt->backPrev; + if (pos < LZMA_NUM_REPS) + state = kRepNextStates[state]; + else + state = kMatchNextStates[state]; + } + prevOpt = &p->opt[posPrev]; + if (pos < LZMA_NUM_REPS) + { + UInt32 i; + reps[0] = prevOpt->backs[pos]; + for (i = 1; i <= pos; i++) + reps[i] = prevOpt->backs[i - 1]; + for (; i < LZMA_NUM_REPS; i++) + reps[i] = prevOpt->backs[i]; + } + else + { + UInt32 i; + reps[0] = (pos - LZMA_NUM_REPS); + for (i = 1; i < LZMA_NUM_REPS; i++) + reps[i] = prevOpt->backs[i - 1]; + } + } + curOpt->state = (CState)state; + + curOpt->backs[0] = reps[0]; + curOpt->backs[1] = reps[1]; + curOpt->backs[2] = reps[2]; + curOpt->backs[3] = reps[3]; + + curPrice = curOpt->price; + nextIsChar = False; + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + currentByte = *data; + matchByte = *(data - (reps[0] + 1)); + + posState = (position & p->pbMask); + + curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]); + { + const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); + curAnd1Price += + (!IsCharState(state) ? + LitEnc_GetPriceMatched(probs, currentByte, matchByte, p->ProbPrices) : + LitEnc_GetPrice(probs, currentByte, p->ProbPrices)); + } + + nextOpt = &p->opt[cur + 1]; + + if (curAnd1Price < nextOpt->price) + { + nextOpt->price = curAnd1Price; + nextOpt->posPrev = cur; + MakeAsChar(nextOpt); + nextIsChar = True; + } + + matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]); + repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); + + if (matchByte == currentByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0)) + { + UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState); + if (shortRepPrice <= nextOpt->price) + { + nextOpt->price = shortRepPrice; + nextOpt->posPrev = cur; + MakeAsShortRep(nextOpt); + nextIsChar = True; + } + } + + { + UInt32 temp = kNumOpts - 1 - cur; + if (temp < numAvailableBytesFull) + numAvailableBytesFull = temp; + } + numAvailableBytes = numAvailableBytesFull; + + if (numAvailableBytes < 2) + continue; + if (numAvailableBytes > p->numFastBytes) + numAvailableBytes = p->numFastBytes; + if (!nextIsChar && matchByte != currentByte) /* speed optimization */ + { + /* try Literal + rep0 */ + UInt32 temp; + UInt32 lenTest2; + const Byte *data2 = data - (reps[0] + 1); + UInt32 limit = p->numFastBytes + 1; + if (limit > numAvailableBytesFull) + limit = numAvailableBytesFull; + + for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++); + lenTest2 = temp - 1; + if (lenTest2 >= 2) + { + UInt32 state2 = kLiteralNextStates[state]; + UInt32 posStateNext = (position + 1) & p->pbMask; + UInt32 nextRepMatchPrice = curAnd1Price + + GET_PRICE_1(p->isMatch[state2][posStateNext]) + + GET_PRICE_1(p->isRep[state2]); + /* for (; lenTest2 >= 2; lenTest2--) */ + { + UInt32 curAndLenPrice; + COptimal *opt; + UInt32 offset = cur + 1 + lenTest2; + while (lenEnd < offset) + p->opt[++lenEnd].price = kInfinityPrice; + curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); + opt = &p->opt[offset]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = cur + 1; + opt->backPrev = 0; + opt->prev1IsChar = True; + opt->prev2 = False; + } + } + } + } + + startLen = 2; /* speed optimization */ + { + UInt32 repIndex; + for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++) + { + UInt32 lenTest; + UInt32 lenTestTemp; + UInt32 price; + const Byte *data2 = data - (reps[repIndex] + 1); + if (data[0] != data2[0] || data[1] != data2[1]) + continue; + for (lenTest = 2; lenTest < numAvailableBytes && data[lenTest] == data2[lenTest]; lenTest++); + while (lenEnd < cur + lenTest) + p->opt[++lenEnd].price = kInfinityPrice; + lenTestTemp = lenTest; + price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState); + do + { + UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2]; + COptimal *opt = &p->opt[cur + lenTest]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = cur; + opt->backPrev = repIndex; + opt->prev1IsChar = False; + } + } + while (--lenTest >= 2); + lenTest = lenTestTemp; + + if (repIndex == 0) + startLen = lenTest + 1; + + /* if (_maxMode) */ + { + UInt32 lenTest2 = lenTest + 1; + UInt32 limit = lenTest2 + p->numFastBytes; + UInt32 nextRepMatchPrice; + if (limit > numAvailableBytesFull) + limit = numAvailableBytesFull; + for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); + lenTest2 -= lenTest + 1; + if (lenTest2 >= 2) + { + UInt32 state2 = kRepNextStates[state]; + UInt32 posStateNext = (position + lenTest) & p->pbMask; + UInt32 curAndLenCharPrice = + price + p->repLenEnc.prices[posState][lenTest - 2] + + GET_PRICE_0(p->isMatch[state2][posStateNext]) + + LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), + data[lenTest], data2[lenTest], p->ProbPrices); + state2 = kLiteralNextStates[state2]; + posStateNext = (position + lenTest + 1) & p->pbMask; + nextRepMatchPrice = curAndLenCharPrice + + GET_PRICE_1(p->isMatch[state2][posStateNext]) + + GET_PRICE_1(p->isRep[state2]); + + /* for (; lenTest2 >= 2; lenTest2--) */ + { + UInt32 curAndLenPrice; + COptimal *opt; + UInt32 offset = cur + lenTest + 1 + lenTest2; + while (lenEnd < offset) + p->opt[++lenEnd].price = kInfinityPrice; + curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); + opt = &p->opt[offset]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = cur + lenTest + 1; + opt->backPrev = 0; + opt->prev1IsChar = True; + opt->prev2 = True; + opt->posPrev2 = cur; + opt->backPrev2 = repIndex; + } + } + } + } + } + } + /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */ + if (newLen > numAvailableBytes) + { + newLen = numAvailableBytes; + for (numDistancePairs = 0; newLen > matchDistances[numDistancePairs]; numDistancePairs += 2); + matchDistances[numDistancePairs] = newLen; + numDistancePairs += 2; + } + if (newLen >= startLen) + { + UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]); + UInt32 offs, curBack, posSlot; + UInt32 lenTest; + while (lenEnd < cur + newLen) + p->opt[++lenEnd].price = kInfinityPrice; + + offs = 0; + while (startLen > matchDistances[offs]) + offs += 2; + curBack = matchDistances[offs + 1]; + GetPosSlot2(curBack, posSlot); + for (lenTest = /*2*/ startLen; ; lenTest++) + { + UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN]; + UInt32 lenToPosState = GetLenToPosState(lenTest); + COptimal *opt; + if (curBack < kNumFullDistances) + curAndLenPrice += p->distancesPrices[lenToPosState][curBack]; + else + curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask]; + + opt = &p->opt[cur + lenTest]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = cur; + opt->backPrev = curBack + LZMA_NUM_REPS; + opt->prev1IsChar = False; + } + + if (/*_maxMode && */lenTest == matchDistances[offs]) + { + /* Try Match + Literal + Rep0 */ + const Byte *data2 = data - (curBack + 1); + UInt32 lenTest2 = lenTest + 1; + UInt32 limit = lenTest2 + p->numFastBytes; + UInt32 nextRepMatchPrice; + if (limit > numAvailableBytesFull) + limit = numAvailableBytesFull; + for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); + lenTest2 -= lenTest + 1; + if (lenTest2 >= 2) + { + UInt32 state2 = kMatchNextStates[state]; + UInt32 posStateNext = (position + lenTest) & p->pbMask; + UInt32 curAndLenCharPrice = curAndLenPrice + + GET_PRICE_0(p->isMatch[state2][posStateNext]) + + LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), + data[lenTest], data2[lenTest], p->ProbPrices); + state2 = kLiteralNextStates[state2]; + posStateNext = (posStateNext + 1) & p->pbMask; + nextRepMatchPrice = curAndLenCharPrice + + GET_PRICE_1(p->isMatch[state2][posStateNext]) + + GET_PRICE_1(p->isRep[state2]); + + /* for (; lenTest2 >= 2; lenTest2--) */ + { + UInt32 offset = cur + lenTest + 1 + lenTest2; + UInt32 curAndLenPrice; + COptimal *opt; + while (lenEnd < offset) + p->opt[++lenEnd].price = kInfinityPrice; + curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); + opt = &p->opt[offset]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = cur + lenTest + 1; + opt->backPrev = 0; + opt->prev1IsChar = True; + opt->prev2 = True; + opt->posPrev2 = cur; + opt->backPrev2 = curBack + LZMA_NUM_REPS; + } + } + } + offs += 2; + if (offs == numDistancePairs) + break; + curBack = matchDistances[offs + 1]; + if (curBack >= kNumFullDistances) + GetPosSlot2(curBack, posSlot); + } + } + } + } +} + +#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist)) + +static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) +{ + UInt32 numAvailableBytes = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); + UInt32 lenMain, numDistancePairs; + const Byte *data; + UInt32 repLens[LZMA_NUM_REPS]; + UInt32 repMaxIndex, i; + UInt32 *matchDistances; + UInt32 backMain; + + if (!p->longestMatchWasFound) + { + lenMain = ReadMatchDistances(p, &numDistancePairs); + } + else + { + lenMain = p->longestMatchLength; + numDistancePairs = p->numDistancePairs; + p->longestMatchWasFound = False; + } + + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + if (numAvailableBytes > LZMA_MATCH_LEN_MAX) + numAvailableBytes = LZMA_MATCH_LEN_MAX; + if (numAvailableBytes < 2) + { + *backRes = (UInt32)(-1); + return 1; + } + + repMaxIndex = 0; + + for (i = 0; i < LZMA_NUM_REPS; i++) + { + const Byte *data2 = data - (p->reps[i] + 1); + UInt32 len; + if (data[0] != data2[0] || data[1] != data2[1]) + { + repLens[i] = 0; + continue; + } + for (len = 2; len < numAvailableBytes && data[len] == data2[len]; len++); + if (len >= p->numFastBytes) + { + *backRes = i; + MovePos(p, len - 1); + return len; + } + repLens[i] = len; + if (len > repLens[repMaxIndex]) + repMaxIndex = i; + } + matchDistances = p->matchDistances; + if (lenMain >= p->numFastBytes) + { + *backRes = matchDistances[numDistancePairs - 1] + LZMA_NUM_REPS; + MovePos(p, lenMain - 1); + return lenMain; + } + + backMain = 0; /* for GCC */ + if (lenMain >= 2) + { + backMain = matchDistances[numDistancePairs - 1]; + while (numDistancePairs > 2 && lenMain == matchDistances[numDistancePairs - 4] + 1) + { + if (!ChangePair(matchDistances[numDistancePairs - 3], backMain)) + break; + numDistancePairs -= 2; + lenMain = matchDistances[numDistancePairs - 2]; + backMain = matchDistances[numDistancePairs - 1]; + } + if (lenMain == 2 && backMain >= 0x80) + lenMain = 1; + } + + if (repLens[repMaxIndex] >= 2) + { + if (repLens[repMaxIndex] + 1 >= lenMain || + (repLens[repMaxIndex] + 2 >= lenMain && (backMain > (1 << 9))) || + (repLens[repMaxIndex] + 3 >= lenMain && (backMain > (1 << 15)))) + { + UInt32 lenRes; + *backRes = repMaxIndex; + lenRes = repLens[repMaxIndex]; + MovePos(p, lenRes - 1); + return lenRes; + } + } + + if (lenMain >= 2 && numAvailableBytes > 2) + { + UInt32 i; + numAvailableBytes = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); + p->longestMatchLength = ReadMatchDistances(p, &p->numDistancePairs); + if (p->longestMatchLength >= 2) + { + UInt32 newDistance = matchDistances[p->numDistancePairs - 1]; + if ((p->longestMatchLength >= lenMain && newDistance < backMain) || + (p->longestMatchLength == lenMain + 1 && !ChangePair(backMain, newDistance)) || + (p->longestMatchLength > lenMain + 1) || + (p->longestMatchLength + 1 >= lenMain && lenMain >= 3 && ChangePair(newDistance, backMain))) + { + p->longestMatchWasFound = True; + *backRes = (UInt32)(-1); + return 1; + } + } + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + for (i = 0; i < LZMA_NUM_REPS; i++) + { + UInt32 len; + const Byte *data2 = data - (p->reps[i] + 1); + if (data[1] != data2[1] || data[2] != data2[2]) + { + repLens[i] = 0; + continue; + } + for (len = 2; len < numAvailableBytes && data[len] == data2[len]; len++); + if (len + 1 >= lenMain) + { + p->longestMatchWasFound = True; + *backRes = (UInt32)(-1); + return 1; + } + } + *backRes = backMain + LZMA_NUM_REPS; + MovePos(p, lenMain - 2); + return lenMain; + } + *backRes = (UInt32)(-1); + return 1; +} + +static void WriteEndMarker(CLzmaEnc *p, UInt32 posState) +{ + UInt32 len; + RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); + RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); + p->state = kMatchNextStates[p->state]; + len = LZMA_MATCH_LEN_MIN; + LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); + RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1); + RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits); + RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask); +} + +static SRes CheckErrors(CLzmaEnc *p) +{ + if (p->result != SZ_OK) + return p->result; + if (p->rc.res != SZ_OK) + p->result = SZ_ERROR_WRITE; + if (p->matchFinderBase.result != SZ_OK) + p->result = SZ_ERROR_READ; + if (p->result != SZ_OK) + p->finished = True; + return p->result; +} + +static SRes Flush(CLzmaEnc *p, UInt32 nowPos) +{ + /* ReleaseMFStream(); */ + p->finished = True; + if (p->writeEndMark) + WriteEndMarker(p, nowPos & p->pbMask); + RangeEnc_FlushData(&p->rc); + RangeEnc_FlushStream(&p->rc); + return CheckErrors(p); +} + +static void FillAlignPrices(CLzmaEnc *p) +{ + UInt32 i; + for (i = 0; i < kAlignTableSize; i++) + p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices); + p->alignPriceCount = 0; +} + +static void FillDistancesPrices(CLzmaEnc *p) +{ + UInt32 tempPrices[kNumFullDistances]; + UInt32 i, lenToPosState; + for (i = kStartPosModelIndex; i < kNumFullDistances; i++) + { + UInt32 posSlot = GetPosSlot1(i); + UInt32 footerBits = ((posSlot >> 1) - 1); + UInt32 base = ((2 | (posSlot & 1)) << footerBits); + tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices); + } + + for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) + { + UInt32 posSlot; + const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState]; + UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState]; + for (posSlot = 0; posSlot < p->distTableSize; posSlot++) + posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices); + for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++) + posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits); + + { + UInt32 *distancesPrices = p->distancesPrices[lenToPosState]; + UInt32 i; + for (i = 0; i < kStartPosModelIndex; i++) + distancesPrices[i] = posSlotPrices[i]; + for (; i < kNumFullDistances; i++) + distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i]; + } + } + p->matchPriceCount = 0; +} + +void LzmaEnc_Construct(CLzmaEnc *p) +{ + RangeEnc_Construct(&p->rc); + MatchFinder_Construct(&p->matchFinderBase); + #ifdef COMPRESS_MF_MT + MatchFinderMt_Construct(&p->matchFinderMt); + p->matchFinderMt.MatchFinder = &p->matchFinderBase; + #endif + + { + CLzmaEncProps props; + LzmaEncProps_Init(&props); + LzmaEnc_SetProps(p, &props); + } + + #ifndef LZMA_LOG_BSR + LzmaEnc_FastPosInit(p->g_FastPos); + #endif + + LzmaEnc_InitPriceTables(p->ProbPrices); + p->litProbs = 0; + p->saveState.litProbs = 0; +} + +CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc) +{ + void *p; + p = alloc->Alloc(alloc, sizeof(CLzmaEnc)); + if (p != 0) + LzmaEnc_Construct((CLzmaEnc *)p); + return p; +} + +void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->litProbs); + alloc->Free(alloc, p->saveState.litProbs); + p->litProbs = 0; + p->saveState.litProbs = 0; +} + +void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + #ifdef COMPRESS_MF_MT + MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); + #endif + MatchFinder_Free(&p->matchFinderBase, allocBig); + LzmaEnc_FreeLits(p, alloc); + RangeEnc_Free(&p->rc, alloc); +} + +void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig); + alloc->Free(alloc, p); +} + +static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize) +{ + UInt32 nowPos32, startPos32; + if (p->inStream != 0) + { + p->matchFinderBase.stream = p->inStream; + p->matchFinder.Init(p->matchFinderObj); + p->inStream = 0; + } + + if (p->finished) + return p->result; + RINOK(CheckErrors(p)); + + nowPos32 = (UInt32)p->nowPos64; + startPos32 = nowPos32; + + if (p->nowPos64 == 0) + { + UInt32 numDistancePairs; + Byte curByte; + if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) + return Flush(p, nowPos32); + ReadMatchDistances(p, &numDistancePairs); + RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0); + p->state = kLiteralNextStates[p->state]; + curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset); + LitEnc_Encode(&p->rc, p->litProbs, curByte); + p->additionalOffset--; + nowPos32++; + } + + if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0) + for (;;) + { + UInt32 pos, len, posState; + + if (p->fastMode) + len = GetOptimumFast(p, &pos); + else + len = GetOptimum(p, nowPos32, &pos); + + #ifdef SHOW_STAT2 + printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos); + #endif + + posState = nowPos32 & p->pbMask; + if (len == 1 && pos == 0xFFFFFFFF) + { + Byte curByte; + CLzmaProb *probs; + const Byte *data; + + RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0); + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; + curByte = *data; + probs = LIT_PROBS(nowPos32, *(data - 1)); + if (IsCharState(p->state)) + LitEnc_Encode(&p->rc, probs, curByte); + else + LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1)); + p->state = kLiteralNextStates[p->state]; + } + else + { + RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); + if (pos < LZMA_NUM_REPS) + { + RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1); + if (pos == 0) + { + RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0); + RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1)); + } + else + { + UInt32 distance = p->reps[pos]; + RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1); + if (pos == 1) + RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0); + else + { + RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1); + RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2); + if (pos == 3) + p->reps[3] = p->reps[2]; + p->reps[2] = p->reps[1]; + } + p->reps[1] = p->reps[0]; + p->reps[0] = distance; + } + if (len == 1) + p->state = kShortRepNextStates[p->state]; + else + { + LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); + p->state = kRepNextStates[p->state]; + } + } + else + { + UInt32 posSlot; + RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); + p->state = kMatchNextStates[p->state]; + LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); + pos -= LZMA_NUM_REPS; + GetPosSlot(pos, posSlot); + RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot); + + if (posSlot >= kStartPosModelIndex) + { + UInt32 footerBits = ((posSlot >> 1) - 1); + UInt32 base = ((2 | (posSlot & 1)) << footerBits); + UInt32 posReduced = pos - base; + + if (posSlot < kEndPosModelIndex) + RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced); + else + { + RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits); + RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask); + p->alignPriceCount++; + } + } + p->reps[3] = p->reps[2]; + p->reps[2] = p->reps[1]; + p->reps[1] = p->reps[0]; + p->reps[0] = pos; + p->matchPriceCount++; + } + } + p->additionalOffset -= len; + nowPos32 += len; + if (p->additionalOffset == 0) + { + UInt32 processed; + if (!p->fastMode) + { + if (p->matchPriceCount >= (1 << 7)) + FillDistancesPrices(p); + if (p->alignPriceCount >= kAlignTableSize) + FillAlignPrices(p); + } + if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) + break; + processed = nowPos32 - startPos32; + if (useLimits) + { + if (processed + kNumOpts + 300 >= maxUnpackSize || + RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize) + break; + } + else if (processed >= (1 << 15)) + { + p->nowPos64 += nowPos32 - startPos32; + return CheckErrors(p); + } + } + } + p->nowPos64 += nowPos32 - startPos32; + return Flush(p, nowPos32); +} + +#define kBigHashDicLimit ((UInt32)1 << 24) + +static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + UInt32 beforeSize = kNumOpts; + Bool btMode; + if (!RangeEnc_Alloc(&p->rc, alloc)) + return SZ_ERROR_MEM; + btMode = (p->matchFinderBase.btMode != 0); + #ifdef COMPRESS_MF_MT + p->mtMode = (p->multiThread && !p->fastMode && btMode); + #endif + + { + unsigned lclp = p->lc + p->lp; + if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp) + { + LzmaEnc_FreeLits(p, alloc); + p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); + p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); + if (p->litProbs == 0 || p->saveState.litProbs == 0) + { + LzmaEnc_FreeLits(p, alloc); + return SZ_ERROR_MEM; + } + p->lclp = lclp; + } + } + + p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit); + + if (beforeSize + p->dictSize < keepWindowSize) + beforeSize = keepWindowSize - p->dictSize; + + #ifdef COMPRESS_MF_MT + if (p->mtMode) + { + RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)); + p->matchFinderObj = &p->matchFinderMt; + MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); + } + else + #endif + { + if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)) + return SZ_ERROR_MEM; + p->matchFinderObj = &p->matchFinderBase; + MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder); + } + return SZ_OK; +} + +void LzmaEnc_Init(CLzmaEnc *p) +{ + UInt32 i; + p->state = 0; + for(i = 0 ; i < LZMA_NUM_REPS; i++) + p->reps[i] = 0; + + RangeEnc_Init(&p->rc); + + + for (i = 0; i < kNumStates; i++) + { + UInt32 j; + for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++) + { + p->isMatch[i][j] = kProbInitValue; + p->isRep0Long[i][j] = kProbInitValue; + } + p->isRep[i] = kProbInitValue; + p->isRepG0[i] = kProbInitValue; + p->isRepG1[i] = kProbInitValue; + p->isRepG2[i] = kProbInitValue; + } + + { + UInt32 num = 0x300 << (p->lp + p->lc); + for (i = 0; i < num; i++) + p->litProbs[i] = kProbInitValue; + } + + { + for (i = 0; i < kNumLenToPosStates; i++) + { + CLzmaProb *probs = p->posSlotEncoder[i]; + UInt32 j; + for (j = 0; j < (1 << kNumPosSlotBits); j++) + probs[j] = kProbInitValue; + } + } + { + for(i = 0; i < kNumFullDistances - kEndPosModelIndex; i++) + p->posEncoders[i] = kProbInitValue; + } + + LenEnc_Init(&p->lenEnc.p); + LenEnc_Init(&p->repLenEnc.p); + + for (i = 0; i < (1 << kNumAlignBits); i++) + p->posAlignEncoder[i] = kProbInitValue; + + p->longestMatchWasFound = False; + p->optimumEndIndex = 0; + p->optimumCurrentIndex = 0; + p->additionalOffset = 0; + + p->pbMask = (1 << p->pb) - 1; + p->lpMask = (1 << p->lp) - 1; +} + +void LzmaEnc_InitPrices(CLzmaEnc *p) +{ + if (!p->fastMode) + { + FillDistancesPrices(p); + FillAlignPrices(p); + } + + p->lenEnc.tableSize = + p->repLenEnc.tableSize = + p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN; + LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices); + LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices); +} + +static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + UInt32 i; + for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++) + if (p->dictSize <= ((UInt32)1 << i)) + break; + p->distTableSize = i * 2; + + p->finished = False; + p->result = SZ_OK; + RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)); + LzmaEnc_Init(p); + LzmaEnc_InitPrices(p); + p->nowPos64 = 0; + return SZ_OK; +} + +static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqInStream *inStream, ISeqOutStream *outStream, + ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + p->inStream = inStream; + p->rc.outStream = outStream; + return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); +} + +SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, + ISeqInStream *inStream, UInt32 keepWindowSize, + ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + p->inStream = inStream; + return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); +} + +static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) +{ + p->seqBufInStream.funcTable.Read = MyRead; + p->seqBufInStream.data = src; + p->seqBufInStream.rem = srcLen; +} + +SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, + UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + LzmaEnc_SetInputBuf(p, src, srcLen); + p->inStream = &p->seqBufInStream.funcTable; + return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); +} + +void LzmaEnc_Finish(CLzmaEncHandle pp) +{ + #ifdef COMPRESS_MF_MT + CLzmaEnc *p = (CLzmaEnc *)pp; + if (p->mtMode) + MatchFinderMt_ReleaseStream(&p->matchFinderMt); + #endif +} + +typedef struct _CSeqOutStreamBuf +{ + ISeqOutStream funcTable; + Byte *data; + SizeT rem; + Bool overflow; +} CSeqOutStreamBuf; + +static size_t MyWrite(void *pp, const void *data, size_t size) +{ + CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp; + if (p->rem < size) + { + size = p->rem; + p->overflow = True; + } + memcpy(p->data, data, size); + p->rem -= size; + p->data += size; + return size; +} + + +UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) +{ + const CLzmaEnc *p = (CLzmaEnc *)pp; + return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); +} + +const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) +{ + const CLzmaEnc *p = (CLzmaEnc *)pp; + return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; +} + +SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, + Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + UInt64 nowPos64; + SRes res; + CSeqOutStreamBuf outStream; + + outStream.funcTable.Write = MyWrite; + outStream.data = dest; + outStream.rem = *destLen; + outStream.overflow = False; + + p->writeEndMark = False; + p->finished = False; + p->result = SZ_OK; + + if (reInit) + LzmaEnc_Init(p); + LzmaEnc_InitPrices(p); + nowPos64 = p->nowPos64; + RangeEnc_Init(&p->rc); + p->rc.outStream = &outStream.funcTable; + + res = LzmaEnc_CodeOneBlock(pp, True, desiredPackSize, *unpackSize); + + *unpackSize = (UInt32)(p->nowPos64 - nowPos64); + *destLen -= outStream.rem; + if (outStream.overflow) + return SZ_ERROR_OUTPUT_EOF; + + return res; +} + +SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, + ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + SRes res = SZ_OK; + + #ifdef COMPRESS_MF_MT + Byte allocaDummy[0x300]; + int i = 0; + for (i = 0; i < 16; i++) + allocaDummy[i] = (Byte)i; + #endif + + RINOK(LzmaEnc_Prepare(pp, inStream, outStream, alloc, allocBig)); + + for (;;) + { + res = LzmaEnc_CodeOneBlock(pp, False, 0, 0); + if (res != SZ_OK || p->finished != 0) + break; + if (progress != 0) + { + res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); + if (res != SZ_OK) + { + res = SZ_ERROR_PROGRESS; + break; + } + } + } + LzmaEnc_Finish(pp); + return res; +} + +SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + int i; + UInt32 dictSize = p->dictSize; + if (*size < LZMA_PROPS_SIZE) + return SZ_ERROR_PARAM; + *size = LZMA_PROPS_SIZE; + props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc); + + for (i = 11; i <= 30; i++) + { + if (dictSize <= ((UInt32)2 << i)) + { + dictSize = (2 << i); + break; + } + if (dictSize <= ((UInt32)3 << i)) + { + dictSize = (3 << i); + break; + } + } + + for (i = 0; i < 4; i++) + props[1 + i] = (Byte)(dictSize >> (8 * i)); + return SZ_OK; +} + +SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + SRes res; + CLzmaEnc *p = (CLzmaEnc *)pp; + + CSeqOutStreamBuf outStream; + + LzmaEnc_SetInputBuf(p, src, srcLen); + + outStream.funcTable.Write = MyWrite; + outStream.data = dest; + outStream.rem = *destLen; + outStream.overflow = False; + + p->writeEndMark = writeEndMark; + res = LzmaEnc_Encode(pp, &outStream.funcTable, &p->seqBufInStream.funcTable, + progress, alloc, allocBig); + + *destLen -= outStream.rem; + if (outStream.overflow) + return SZ_ERROR_OUTPUT_EOF; + return res; +} + +SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, + ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); + SRes res; + if (p == 0) + return SZ_ERROR_MEM; + + res = LzmaEnc_SetProps(p, props); + if (res == SZ_OK) + { + res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize); + if (res == SZ_OK) + res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen, + writeEndMark, progress, alloc, allocBig); + } + + LzmaEnc_Destroy(p, alloc, allocBig); + return res; +} diff --git a/C/LzmaEnc.h b/C/LzmaEnc.h new file mode 100755 index 00000000..949f40f4 --- /dev/null +++ b/C/LzmaEnc.h @@ -0,0 +1,74 @@ +/* LzmaEnc.h -- LZMA Encoder +2008-04-27 +Copyright (c) 1999-2008 Igor Pavlov +Read LzFind.h for license options */ + +#ifndef __LZMAENC_H +#define __LZMAENC_H + +#include "Types.h" + +#define LZMA_PROPS_SIZE 5 + +typedef struct _CLzmaEncProps +{ + int level; /* 0 <= level <= 9 */ + UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version + (1 << 12) <= dictSize <= (1 << 30) for 64-bit version + default = (1 << 24) */ + int lc; /* 0 <= lc <= 8, default = 3 */ + int lp; /* 0 <= lp <= 4, default = 0 */ + int pb; /* 0 <= pb <= 4, default = 2 */ + int algo; /* 0 - fast, 1 - normal, default = 1 */ + int fb; /* 5 <= fb <= 273, default = 32 */ + int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ + int numHashBytes; /* 2, 3 or 4, default = 4 */ + UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ + unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ + int numThreads; /* 1 or 2, default = 2 */ +} CLzmaEncProps; + +void LzmaEncProps_Init(CLzmaEncProps *p); +void LzmaEncProps_Normalize(CLzmaEncProps *p); +UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); + + +/* ---------- CLzmaEncHandle Interface ---------- */ + +/* LzmaEnc_* functions can return the following exit codes: +Returns: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater in props + SZ_ERROR_WRITE - Write callback error. + SZ_ERROR_PROGRESS - some break from progress callback + SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) +*/ + +typedef void * CLzmaEncHandle; + +CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc); +void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); +SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); +SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); +SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, + ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); +SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); + +/* ---------- One Call Interface ---------- */ + +/* LzmaEncode +Return code: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater + SZ_ERROR_OUTPUT_EOF - output buffer overflow + SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) +*/ + +SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, + ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); + +#endif diff --git a/C/LzmaLib.c b/C/LzmaLib.c new file mode 100755 index 00000000..32b0a459 --- /dev/null +++ b/C/LzmaLib.c @@ -0,0 +1,46 @@ +/* LzmaLib.c -- LZMA library wrapper +2008-04-07 +Igor Pavlov +Public domain */ + +#include "LzmaEnc.h" +#include "LzmaDec.h" +#include "Alloc.h" +#include "LzmaLib.h" + +static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } +static void SzFree(void *p, void *address) { p = p; MyFree(address); } +static ISzAlloc g_Alloc = { SzAlloc, SzFree }; + +MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, + unsigned char *outProps, size_t *outPropsSize, + int level, /* 0 <= level <= 9, default = 5 */ + unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */ + int lc, /* 0 <= lc <= 8, default = 3 */ + int lp, /* 0 <= lp <= 4, default = 0 */ + int pb, /* 0 <= pb <= 4, default = 2 */ + int fb, /* 5 <= fb <= 273, default = 32 */ + int numThreads /* 1 or 2, default = 2 */ +) +{ + CLzmaEncProps props; + LzmaEncProps_Init(&props); + props.level = level; + props.dictSize = dictSize; + props.lc = lc; + props.lp = lp; + props.pb = pb; + props.fb = fb; + props.numThreads = numThreads; + + return LzmaEncode(dest, destLen, src, srcLen, &props, outProps, outPropsSize, 0, + NULL, &g_Alloc, &g_Alloc); +} + + +MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen, + const unsigned char *props, size_t propsSize) +{ + ELzmaStatus status; + return LzmaDecode(dest, destLen, src, srcLen, props, (unsigned)propsSize, LZMA_FINISH_ANY, &status, &g_Alloc); +} diff --git a/C/LzmaLib.h b/C/LzmaLib.h new file mode 100755 index 00000000..ac7f90f8 --- /dev/null +++ b/C/LzmaLib.h @@ -0,0 +1,135 @@ +/* LzmaLib.h -- LZMA library interface +2008-04-11 +Igor Pavlov +Public domain */ + +#ifndef __LZMALIB_H +#define __LZMALIB_H + +#include "Types.h" + +#ifdef __cplusplus + #define MY_EXTERN_C extern "C" +#else + #define MY_EXTERN_C extern +#endif + +#define MY_STDAPI MY_EXTERN_C int MY_STD_CALL + +#define LZMA_PROPS_SIZE 5 + +/* +RAM requirements for LZMA: + for compression: (dictSize * 11.5 + 6 MB) + state_size + for decompression: dictSize + state_size + state_size = (4 + (1.5 << (lc + lp))) KB + by default (lc=3, lp=0), state_size = 16 KB. + +LZMA properties (5 bytes) format + Offset Size Description + 0 1 lc, lp and pb in encoded form. + 1 4 dictSize (little endian). +*/ + +/* +LzmaCompress +------------ + +outPropsSize - + In: the pointer to the size of outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5. + Out: the pointer to the size of written properties in outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5. + + LZMA Encoder will use defult values for any parameter, if it is + -1 for any from: level, loc, lp, pb, fb, numThreads + 0 for dictSize + +level - compression level: 0 <= level <= 9; + + level dictSize algo fb + 0: 16 KB 0 32 + 1: 64 KB 0 32 + 2: 256 KB 0 32 + 3: 1 MB 0 32 + 4: 4 MB 0 32 + 5: 16 MB 1 32 + 6: 32 MB 1 32 + 7+: 64 MB 1 64 + + The default value for "level" is 5. + + algo = 0 means fast method + algo = 1 means normal method + +dictSize - The dictionary size in bytes. The maximum value is + 128 MB = (1 << 27) bytes for 32-bit version + 1 GB = (1 << 30) bytes for 64-bit version + The default value is 16 MB = (1 << 24) bytes. + It's recommended to use the dictionary that is larger than 4 KB and + that can be calculated as (1 << N) or (3 << N) sizes. + +lc - The number of literal context bits (high bits of previous literal). + It can be in the range from 0 to 8. The default value is 3. + Sometimes lc=4 gives the gain for big files. + +lp - The number of literal pos bits (low bits of current position for literals). + It can be in the range from 0 to 4. The default value is 0. + The lp switch is intended for periodical data when the period is equal to 2^lp. + For example, for 32-bit (4 bytes) periodical data you can use lp=2. Often it's + better to set lc=0, if you change lp switch. + +pb - The number of pos bits (low bits of current position). + It can be in the range from 0 to 4. The default value is 2. + The pb switch is intended for periodical data when the period is equal 2^pb. + +fb - Word size (the number of fast bytes). + It can be in the range from 5 to 273. The default value is 32. + Usually, a big number gives a little bit better compression ratio and + slower compression process. + +numThreads - The number of thereads. 1 or 2. The default value is 2. + Fast mode (algo = 0) can use only 1 thread. + +Out: + destLen - processed output size +Returns: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater + SZ_ERROR_OUTPUT_EOF - output buffer overflow + SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) +*/ + +MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, + unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */ + int level, /* 0 <= level <= 9, default = 5 */ + unsigned dictSize, /* default = (1 << 24) */ + int lc, /* 0 <= lc <= 8, default = 3 */ + int lp, /* 0 <= lp <= 4, default = 0 */ + int pb, /* 0 <= pb <= 4, default = 2 */ + int fb, /* 5 <= fb <= 273, default = 32 */ + int numThreads /* 1 or 2, default = 2 */ + ); + +/* +LzmaUncompress +-------------- +In: + dest - output data + destLen - output data size + src - input data + srcLen - input data size +Out: + destLen - processed output size + srcLen - processed input size +Returns: + SZ_OK - OK + SZ_ERROR_DATA - Data error + SZ_ERROR_MEM - Memory allocation arror + SZ_ERROR_UNSUPPORTED - Unsupported properties + SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src) +*/ + +MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen, + const unsigned char *props, size_t propsSize); + +#endif diff --git a/C/LzmaLib/LzmaLib.def b/C/LzmaLib/LzmaLib.def new file mode 100755 index 00000000..8bc6add9 --- /dev/null +++ b/C/LzmaLib/LzmaLib.def @@ -0,0 +1,4 @@ +EXPORTS + LzmaCompress + LzmaUncompress + diff --git a/C/LzmaLib/LzmaLib.dsp b/C/LzmaLib/LzmaLib.dsp new file mode 100755 index 00000000..3ba6d254 --- /dev/null +++ b/C/LzmaLib/LzmaLib.dsp @@ -0,0 +1,178 @@ +# Microsoft Developer Studio Project File - Name="LzmaLib" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=LzmaLib - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "LzmaLib.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "LzmaLib.mak" CFG="LzmaLib - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "LzmaLib - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "LzmaLib - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "LzmaLib - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gr /MT /W3 /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /D "COMPRESS_MF_MT" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Util\LZMA.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "LzmaLib - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /D "COMPRESS_MF_MT" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Util\LZMA.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "LzmaLib - Win32 Release" +# Name "LzmaLib - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\LzmaLib.def +# End Source File +# Begin Source File + +SOURCE=.\LzmaLibExports.c +# End Source File +# End Group +# Begin Source File + +SOURCE=..\Alloc.c +# End Source File +# Begin Source File + +SOURCE=..\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\IStream.h +# End Source File +# Begin Source File + +SOURCE=..\LzFind.c +# End Source File +# Begin Source File + +SOURCE=..\LzFind.h +# End Source File +# Begin Source File + +SOURCE=..\LzFindMt.c +# End Source File +# Begin Source File + +SOURCE=..\LzFindMt.h +# End Source File +# Begin Source File + +SOURCE=..\LzHash.h +# End Source File +# Begin Source File + +SOURCE=..\LzmaDec.c +# End Source File +# Begin Source File + +SOURCE=..\LzmaDec.h +# End Source File +# Begin Source File + +SOURCE=..\LzmaEnc.c +# End Source File +# Begin Source File + +SOURCE=..\LzmaEnc.h +# End Source File +# Begin Source File + +SOURCE=..\LzmaLib.c +# End Source File +# Begin Source File + +SOURCE=..\LzmaLib.h +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=..\Threads.c +# End Source File +# Begin Source File + +SOURCE=..\Threads.h +# End Source File +# Begin Source File + +SOURCE=..\Types.h +# End Source File +# End Target +# End Project diff --git a/C/LzmaLib/LzmaLib.dsw b/C/LzmaLib/LzmaLib.dsw new file mode 100755 index 00000000..6faf3336 --- /dev/null +++ b/C/LzmaLib/LzmaLib.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "LzmaLib"=.\LzmaLib.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/C/LzmaLib/LzmaLibExports.c b/C/LzmaLib/LzmaLibExports.c new file mode 100755 index 00000000..cc90cc0b --- /dev/null +++ b/C/LzmaLib/LzmaLibExports.c @@ -0,0 +1,14 @@ +/* LzmaLibExports.c -- LZMA library DLL Entry point +2008-03-26 +Igor Pavlov +Public domain */ + +#include <windows.h> + +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) +{ + hInstance = hInstance; + dwReason = dwReason; + lpReserved = lpReserved; + return TRUE; +} diff --git a/C/LzmaLib/makefile b/C/LzmaLib/makefile new file mode 100755 index 00000000..01c86cb3 --- /dev/null +++ b/C/LzmaLib/makefile @@ -0,0 +1,37 @@ +MY_STATIC_LINK=1 +SLIB = sLZMA.lib +PROG = LZMA.dll +SLIBPATH = $O\$(SLIB) + +DEF_FILE = LzmaLib.def +CFLAGS = $(CFLAGS) \ + -DCOMPRESS_MF_MT \ + +LIBS = $(LIBS) oleaut32.lib + +LIB_OBJS = \ + $O\LzmaLibExports.obj \ + +C_OBJS = \ + $O\Alloc.obj \ + $O\LzFind.obj \ + $O\LzFindMt.obj \ + $O\LzmaDec.obj \ + $O\LzmaEnc.obj \ + $O\LzmaLib.obj \ + $O\Threads.obj \ + +OBJS = \ + $(LIB_OBJS) \ + $(C_OBJS) \ + $O\resource.res + +!include "../../CPP/Build.mak" + +$(SLIBPATH): $O $(OBJS) + lib -out:$(SLIBPATH) $(OBJS) $(LIBS) + +$(LIB_OBJS): $(*B).c + $(COMPL_O2) +$(C_OBJS): ../$(*B).c + $(COMPL_O2) diff --git a/C/LzmaLib/resource.rc b/C/LzmaLib/resource.rc new file mode 100755 index 00000000..1e489161 --- /dev/null +++ b/C/LzmaLib/resource.rc @@ -0,0 +1,4 @@ +#include "../../CPP/7zip/MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("LZMA library", "LZMA") + diff --git a/C/LzmaUtil/Lzma86Dec.c b/C/LzmaUtil/Lzma86Dec.c new file mode 100755 index 00000000..b801dd1c --- /dev/null +++ b/C/LzmaUtil/Lzma86Dec.c @@ -0,0 +1,61 @@ +/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder +2008-04-07 +Igor Pavlov +Public domain */ + +#include "Lzma86Dec.h" + +#include "../Alloc.h" +#include "../Bra.h" +#include "../LzmaDec.h" + +#define LZMA86_SIZE_OFFSET (1 + LZMA_PROPS_SIZE) +#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8) + +static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } +static void SzFree(void *p, void *address) { p = p; MyFree(address); } +static ISzAlloc g_Alloc = { SzAlloc, SzFree }; + +SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize) +{ + unsigned i; + if (srcLen < LZMA86_HEADER_SIZE) + return SZ_ERROR_INPUT_EOF; + *unpackSize = 0; + for (i = 0; i < sizeof(UInt64); i++) + *unpackSize += ((UInt64)src[LZMA86_SIZE_OFFSET + i]) << (8 * i); + return SZ_OK; +} + +SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen) +{ + SRes res; + int useFilter; + SizeT inSizePure; + ELzmaStatus status; + + if (*srcLen < LZMA86_HEADER_SIZE) + return SZ_ERROR_INPUT_EOF; + + useFilter = src[0]; + + if (useFilter > 1) + { + *destLen = 0; + return SZ_ERROR_UNSUPPORTED; + } + + inSizePure = *srcLen - LZMA86_HEADER_SIZE; + res = LzmaDecode(dest, destLen, src + LZMA86_HEADER_SIZE, &inSizePure, + src + 1, LZMA_PROPS_SIZE, LZMA_FINISH_ANY, &status, &g_Alloc); + *srcLen = inSizePure + LZMA86_HEADER_SIZE; + if (res != SZ_OK) + return res; + if (useFilter == 1) + { + UInt32 x86State; + x86_Convert_Init(x86State); + x86_Convert(dest, *destLen, 0, &x86State, 0); + } + return SZ_OK; +} diff --git a/C/LzmaUtil/Lzma86Dec.h b/C/LzmaUtil/Lzma86Dec.h new file mode 100755 index 00000000..702a37ba --- /dev/null +++ b/C/LzmaUtil/Lzma86Dec.h @@ -0,0 +1,45 @@ +/* Lzma86Dec.h -- LZMA + x86 (BCJ) Filter Decoder +2008-04-07 +Igor Pavlov +Public domain */ + +#ifndef __LZMA86DEC_H +#define __LZMA86DEC_H + +#include "../Types.h" + +/* +Lzma86_GetUnpackSize: + In: + src - input data + srcLen - input data size + Out: + unpackSize - size of uncompressed stream + Return code: + SZ_OK - OK + SZ_ERROR_INPUT_EOF - Error in headers +*/ + +SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize); + +/* +Lzma86_Decode: + In: + dest - output data + destLen - output data size + src - input data + srcLen - input data size + Out: + destLen - processed output size + srcLen - processed input size + Return code: + SZ_OK - OK + SZ_ERROR_DATA - Data error + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - unsupported file + SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer +*/ + +SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen); + +#endif diff --git a/C/LzmaUtil/Lzma86Enc.c b/C/LzmaUtil/Lzma86Enc.c new file mode 100755 index 00000000..f058e38f --- /dev/null +++ b/C/LzmaUtil/Lzma86Enc.c @@ -0,0 +1,113 @@ +/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder +2008-04-07 +Igor Pavlov +Public domain */ + +#include <string.h> + +#include "Lzma86Enc.h" + +#include "../Alloc.h" +#include "../Bra.h" +#include "../LzmaEnc.h" + +#define SZE_OUT_OVERFLOW SZE_DATA_ERROR + +static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } +static void SzFree(void *p, void *address) { p = p; MyFree(address); } +static ISzAlloc g_Alloc = { SzAlloc, SzFree }; + +#define LZMA86_SIZE_OFFSET (1 + LZMA_PROPS_SIZE) +#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8) + +int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, + int level, UInt32 dictSize, int filterMode) +{ + size_t outSize2 = *destLen; + Byte *filteredStream; + Bool useFilter; + int mainResult = SZ_ERROR_OUTPUT_EOF; + CLzmaEncProps props; + LzmaEncProps_Init(&props); + props.level = level; + props.dictSize = dictSize; + + *destLen = 0; + if (outSize2 < LZMA86_HEADER_SIZE) + return SZ_ERROR_OUTPUT_EOF; + + { + int i; + UInt64 t = srcLen; + for (i = 0; i < 8; i++, t >>= 8) + dest[LZMA86_SIZE_OFFSET + i] = (Byte)t; + } + + filteredStream = 0; + useFilter = (filterMode != SZ_FILTER_NO); + if (useFilter) + { + if (srcLen != 0) + { + filteredStream = (Byte *)MyAlloc(srcLen); + if (filteredStream == 0) + return SZ_ERROR_MEM; + memcpy(filteredStream, src, srcLen); + } + { + UInt32 x86State; + x86_Convert_Init(x86State); + x86_Convert(filteredStream, srcLen, 0, &x86State, 1); + } + } + + { + size_t minSize = 0; + Bool bestIsFiltered = False; + + /* passes for SZ_FILTER_AUTO: + 0 - BCJ + LZMA + 1 - LZMA + 2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better. + */ + int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1; + + int i; + for (i = 0; i < numPasses; i++) + { + size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE; + size_t outPropsSize = 5; + SRes curRes; + Bool curModeIsFiltered = (numPasses > 1 && i == numPasses - 1); + if (curModeIsFiltered && !bestIsFiltered) + break; + if (useFilter && i == 0) + curModeIsFiltered = True; + + curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed, + curModeIsFiltered ? filteredStream : src, srcLen, + &props, dest + 1, &outPropsSize, 0, + NULL, &g_Alloc, &g_Alloc); + + if (curRes != SZ_ERROR_OUTPUT_EOF) + { + if (curRes != SZ_OK) + { + mainResult = curRes; + break; + } + if (outSizeProcessed <= minSize || mainResult != SZ_OK) + { + minSize = outSizeProcessed; + bestIsFiltered = curModeIsFiltered; + mainResult = SZ_OK; + } + } + } + dest[0] = (bestIsFiltered ? 1 : 0); + *destLen = LZMA86_HEADER_SIZE + minSize; + } + if (useFilter) + MyFree(filteredStream); + return mainResult; +} diff --git a/C/LzmaUtil/Lzma86Enc.h b/C/LzmaUtil/Lzma86Enc.h new file mode 100755 index 00000000..03258782 --- /dev/null +++ b/C/LzmaUtil/Lzma86Enc.h @@ -0,0 +1,72 @@ +/* Lzma86Enc.h -- LZMA + x86 (BCJ) Filter Encoder +2008-04-07 +Igor Pavlov +Public domain */ + +#ifndef __LZMA86ENC_H +#define __LZMA86ENC_H + +#include "../Types.h" + +/* +It's an example for LZMA + x86 Filter use. +You can use .lzma86 extension, if you write that stream to file. +.lzma86 header adds one additional byte to standard .lzma header. +.lzma86 header (14 bytes): + Offset Size Description + 0 1 = 0 - no filter, + = 1 - x86 filter + 1 1 lc, lp and pb in encoded form + 2 4 dictSize (little endian) + 6 8 uncompressed size (little endian) + + +Lzma86_Encode +------------- +level - compression level: 0 <= level <= 9, the default value for "level" is 5. + + +dictSize - The dictionary size in bytes. The maximum value is + 128 MB = (1 << 27) bytes for 32-bit version + 1 GB = (1 << 30) bytes for 64-bit version + The default value is 16 MB = (1 << 24) bytes, for level = 5. + It's recommended to use the dictionary that is larger than 4 KB and + that can be calculated as (1 << N) or (3 << N) sizes. + For better compression ratio dictSize must be >= inSize. + +filterMode: + SZ_FILTER_NO - no Filter + SZ_FILTER_YES - x86 Filter + SZ_FILTER_AUTO - it tries both alternatives to select best. + Encoder will use 2 or 3 passes: + 2 passes when FILTER_NO provides better compression. + 3 passes when FILTER_YES provides better compression. + +Lzma86Encode allocates Data with MyAlloc functions. +RAM Requirements for compressing: + RamSize = dictionarySize * 11.5 + 6MB + FilterBlockSize + filterMode FilterBlockSize + SZ_FILTER_NO 0 + SZ_FILTER_YES inSize + SZ_FILTER_AUTO inSize + + +Return code: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater + SZ_ERROR_OUTPUT_EOF - output buffer overflow + SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) +*/ + +enum ESzFilterMode +{ + SZ_FILTER_NO, + SZ_FILTER_YES, + SZ_FILTER_AUTO +}; + +SRes Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, + int level, UInt32 dictSize, int filterMode); + +#endif diff --git a/C/LzmaUtil/LzmaUtil.c b/C/LzmaUtil/LzmaUtil.c new file mode 100755 index 00000000..a7f3bdff --- /dev/null +++ b/C/LzmaUtil/LzmaUtil.c @@ -0,0 +1,311 @@ +/* LzmaUtil.c -- Test application for LZMA compression +2008-04-29 +Igor Pavlov +public domain */ + +#define _CRT_SECURE_NO_WARNINGS + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "../LzmaDec.h" +#include "../LzmaEnc.h" +#include "../Alloc.h" + +const char *kCantReadMessage = "Can not read input file"; +const char *kCantWriteMessage = "Can not write output file"; +const char *kCantAllocateMessage = "Can not allocate memory"; +const char *kDataErrorMessage = "Data error"; + +static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } +static void SzFree(void *p, void *address) { p = p; MyFree(address); } +static ISzAlloc g_Alloc = { SzAlloc, SzFree }; + +#define kInBufferSize (1 << 15) +#define kOutBufferSize (1 << 15) + +unsigned char g_InBuffer[kInBufferSize]; +unsigned char g_OutBuffer[kOutBufferSize]; + +size_t MyReadFile(FILE *file, void *data, size_t size) + { return fread(data, 1, size, file); } + +int MyReadFileAndCheck(FILE *file, void *data, size_t size) + { return (MyReadFile(file, data, size) == size); } + +size_t MyWriteFile(FILE *file, const void *data, size_t size) +{ + if (size == 0) + return 0; + return fwrite(data, 1, size, file); +} + +int MyWriteFileAndCheck(FILE *file, const void *data, size_t size) + { return (MyWriteFile(file, data, size) == size); } + +long MyGetFileLength(FILE *file) +{ + long length; + fseek(file, 0, SEEK_END); + length = ftell(file); + fseek(file, 0, SEEK_SET); + return length; +} + +void PrintHelp(char *buffer) +{ + strcat(buffer, "\nLZMA Utility 4.58 Copyright (c) 1999-2008 Igor Pavlov 2008-04-11\n" + "\nUsage: lzma <e|d> inputFile outputFile\n" + " e: encode file\n" + " d: decode file\n"); +} + +int PrintError(char *buffer, const char *message) +{ + strcat(buffer, "\nError: "); + strcat(buffer, message); + strcat(buffer, "\n"); + return 1; +} + +int PrintErrorNumber(char *buffer, SRes val) +{ + sprintf(buffer + strlen(buffer), "\nError code: %x\n", (unsigned)val); + return 1; +} + +int PrintUserError(char *buffer) +{ + return PrintError(buffer, "Incorrect command"); +} + +#define IN_BUF_SIZE (1 << 16) +#define OUT_BUF_SIZE (1 << 16) + +static int Decode(FILE *inFile, FILE *outFile, char *rs) +{ + UInt64 unpackSize; + int thereIsSize; /* = 1, if there is uncompressed size in headers */ + int i; + int res = 0; + + CLzmaDec state; + + /* header: 5 bytes of LZMA properties and 8 bytes of uncompressed size */ + unsigned char header[LZMA_PROPS_SIZE + 8]; + + /* Read and parse header */ + + if (!MyReadFileAndCheck(inFile, header, sizeof(header))) + return PrintError(rs, kCantReadMessage); + + unpackSize = 0; + thereIsSize = 0; + for (i = 0; i < 8; i++) + { + unsigned char b = header[LZMA_PROPS_SIZE + i]; + if (b != 0xFF) + thereIsSize = 1; + unpackSize += (UInt64)b << (i * 8); + } + + LzmaDec_Construct(&state); + res = LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc); + if (res != SZ_OK) + return res; + { + Byte inBuf[IN_BUF_SIZE]; + Byte outBuf[OUT_BUF_SIZE]; + size_t inPos = 0, inSize = 0, outPos = 0; + LzmaDec_Init(&state); + for (;;) + { + if (inPos == inSize) + { + inSize = MyReadFile(inFile, inBuf, IN_BUF_SIZE); + inPos = 0; + } + { + SizeT inProcessed = inSize - inPos; + SizeT outProcessed = OUT_BUF_SIZE - outPos; + ELzmaFinishMode finishMode = LZMA_FINISH_ANY; + ELzmaStatus status; + if (thereIsSize && outProcessed > unpackSize) + { + outProcessed = (SizeT)unpackSize; + finishMode = LZMA_FINISH_END; + } + + res = LzmaDec_DecodeToBuf(&state, outBuf + outPos, &outProcessed, + inBuf + inPos, &inProcessed, finishMode, &status); + inPos += (UInt32)inProcessed; + outPos += outProcessed; + unpackSize -= outProcessed; + + if (outFile != 0) + MyWriteFile(outFile, outBuf, outPos); + outPos = 0; + + if (res != SZ_OK || thereIsSize && unpackSize == 0) + break; + + if (inProcessed == 0 && outProcessed == 0) + { + if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK) + res = SZ_ERROR_DATA; + break; + } + } + } + } + + LzmaDec_Free(&state, &g_Alloc); + return res; +} + +typedef struct _CFileSeqInStream +{ + ISeqInStream funcTable; + FILE *file; +} CFileSeqInStream; + +static SRes MyRead(void *p, void *buf, size_t *size) +{ + if (*size == 0) + return SZ_OK; + *size = MyReadFile(((CFileSeqInStream*)p)->file, buf, *size); + /* + if (*size == 0) + return SZE_FAIL; + */ + return SZ_OK; +} + +typedef struct _CFileSeqOutStream +{ + ISeqOutStream funcTable; + FILE *file; +} CFileSeqOutStream; + +static size_t MyWrite(void *pp, const void *buf, size_t size) +{ + return MyWriteFile(((CFileSeqOutStream *)pp)->file, buf, size); +} + +static SRes Encode(FILE *inFile, FILE *outFile, char *rs) +{ + CLzmaEncHandle enc; + SRes res; + CFileSeqInStream inStream; + CFileSeqOutStream outStream; + CLzmaEncProps props; + + enc = LzmaEnc_Create(&g_Alloc); + if (enc == 0) + return SZ_ERROR_MEM; + + inStream.funcTable.Read = MyRead; + inStream.file = inFile; + outStream.funcTable.Write = MyWrite; + outStream.file = outFile; + + LzmaEncProps_Init(&props); + res = LzmaEnc_SetProps(enc, &props); + + if (res == SZ_OK) + { + Byte header[LZMA_PROPS_SIZE + 8]; + size_t headerSize = LZMA_PROPS_SIZE; + UInt64 fileSize; + int i; + + res = LzmaEnc_WriteProperties(enc, header, &headerSize); + fileSize = MyGetFileLength(inFile); + for (i = 0; i < 8; i++) + header[headerSize++] = (Byte)(fileSize >> (8 * i)); + if (!MyWriteFileAndCheck(outFile, header, headerSize)) + return PrintError(rs, "writing error"); + + if (res == SZ_OK) + res = LzmaEnc_Encode(enc, &outStream.funcTable, &inStream.funcTable, + NULL, &g_Alloc, &g_Alloc); + } + LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc); + return res; +} + +int main2(int numArgs, const char *args[], char *rs) +{ + FILE *inFile = 0; + FILE *outFile = 0; + char c; + int res; + int encodeMode; + + if (numArgs == 1) + { + PrintHelp(rs); + return 0; + } + + if (numArgs < 3 || numArgs > 4 || strlen(args[1]) != 1) + return PrintUserError(rs); + + c = args[1][0]; + encodeMode = (c == 'e' || c == 'E'); + if (!encodeMode && c != 'd' && c != 'D') + return PrintUserError(rs); + + { + size_t t4 = sizeof(UInt32); + size_t t8 = sizeof(UInt64); + if (t4 != 4 || t8 != 8) + return PrintError(rs, "LZMA UTil needs correct UInt32 and UInt64"); + } + + inFile = fopen(args[2], "rb"); + if (inFile == 0) + return PrintError(rs, "Can not open input file"); + + if (numArgs > 3) + { + outFile = fopen(args[3], "wb+"); + if (outFile == 0) + return PrintError(rs, "Can not open output file"); + } + else if (encodeMode) + PrintUserError(rs); + + if (encodeMode) + { + res = Encode(inFile, outFile, rs); + } + else + { + res = Decode(inFile, outFile, rs); + } + + if (outFile != 0) + fclose(outFile); + fclose(inFile); + + if (res != SZ_OK) + { + if (res == SZ_ERROR_MEM) + return PrintError(rs, kCantAllocateMessage); + else if (res == SZ_ERROR_DATA) + return PrintError(rs, kDataErrorMessage); + else + return PrintErrorNumber(rs, res); + } + return 0; +} + +int MY_CDECL main(int numArgs, const char *args[]) +{ + char rs[800] = { 0 }; + int res = main2(numArgs, args, rs); + printf(rs); + return res; +} diff --git a/C/LzmaUtil/LzmaUtil.dsp b/C/LzmaUtil/LzmaUtil.dsp new file mode 100755 index 00000000..77c03edd --- /dev/null +++ b/C/LzmaUtil/LzmaUtil.dsp @@ -0,0 +1,152 @@ +# Microsoft Developer Studio Project File - Name="LzmaUtil" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=LzmaUtil - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "LzmaUtil.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "LzmaUtil.mak" CFG="LzmaUtil - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "LzmaUtil - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "LzmaUtil - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "LzmaUtil - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\util\lzmac.exe" + +!ELSEIF "$(CFG)" == "LzmaUtil - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\util\lzmac.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "LzmaUtil - Win32 Release" +# Name "LzmaUtil - Win32 Debug" +# Begin Source File + +SOURCE=..\Alloc.c +# End Source File +# Begin Source File + +SOURCE=..\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\CpuArch.h +# End Source File +# Begin Source File + +SOURCE=..\LzFind.c +# End Source File +# Begin Source File + +SOURCE=..\LzFind.h +# End Source File +# Begin Source File + +SOURCE=..\LzFindMt.c +# End Source File +# Begin Source File + +SOURCE=..\LzFindMt.h +# End Source File +# Begin Source File + +SOURCE=..\LzHash.h +# End Source File +# Begin Source File + +SOURCE=..\LzmaDec.c +# End Source File +# Begin Source File + +SOURCE=..\LzmaDec.h +# End Source File +# Begin Source File + +SOURCE=..\LzmaEnc.c +# End Source File +# Begin Source File + +SOURCE=..\LzmaEnc.h +# End Source File +# Begin Source File + +SOURCE=.\LzmaUtil.c +# End Source File +# Begin Source File + +SOURCE=..\Threads.c +# End Source File +# Begin Source File + +SOURCE=..\Threads.h +# End Source File +# Begin Source File + +SOURCE=..\Types.h +# End Source File +# End Target +# End Project diff --git a/C/LzmaUtil/LzmaUtil.dsw b/C/LzmaUtil/LzmaUtil.dsw new file mode 100755 index 00000000..c52eaf6d --- /dev/null +++ b/C/LzmaUtil/LzmaUtil.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "LzmaUtil"=.\LzmaUtil.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/C/LzmaUtil/makefile b/C/LzmaUtil/makefile new file mode 100755 index 00000000..11cada4e --- /dev/null +++ b/C/LzmaUtil/makefile @@ -0,0 +1,27 @@ +MY_STATIC_LINK=1 +PROG = LZMAc.exe + +CFLAGS = $(CFLAGS) \ + -DCOMPRESS_MF_MT \ + +LIB_OBJS = \ + $O\LzmaUtil.obj \ + +C_OBJS = \ + $O\Alloc.obj \ + $O\LzFind.obj \ + $O\LzFindMt.obj \ + $O\LzmaDec.obj \ + $O\LzmaEnc.obj \ + $O\Threads.obj \ + +OBJS = \ + $(LIB_OBJS) \ + $(C_OBJS) \ + +!include "../../CPP/Build.mak" + +$(LIB_OBJS): $(*B).c + $(COMPL_O2) +$(C_OBJS): ../$(*B).c + $(COMPL_O2) diff --git a/C/LzmaUtil/makefile.gcc b/C/LzmaUtil/makefile.gcc new file mode 100755 index 00000000..bfcdc3c3 --- /dev/null +++ b/C/LzmaUtil/makefile.gcc @@ -0,0 +1,36 @@ +PROG = lzma +CXX = g++ +LIB = +RM = rm -f +CFLAGS = -c -O2 -Wall + +OBJS = \ + LzmaUtil.o \ + Alloc.o \ + LzFind.o \ + LzmaDec.o \ + LzmaEnc.o \ + + +all: $(PROG) + +$(PROG): $(OBJS) + $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB) $(LIB2) + +LzmaUtil.o: LzmaUtil.c + $(CXX) $(CFLAGS) LzmaUtil.c + +Alloc.o: ../Alloc.c + $(CXX) $(CFLAGS) ../Alloc.c + +LzFind.o: ../LzFind.c + $(CXX) $(CFLAGS) ../LzFind.c + +LzmaDec.o: ../LzmaDec.c + $(CXX) $(CFLAGS) ../LzmaDec.c + +LzmaEnc.o: ../LzmaEnc.c + $(CXX) $(CFLAGS) ../LzmaEnc.c + +clean: + -$(RM) $(PROG) $(OBJS) diff --git a/C/RotateDefs.h b/C/RotateDefs.h new file mode 100755 index 00000000..cd666271 --- /dev/null +++ b/C/RotateDefs.h @@ -0,0 +1,22 @@ +/* RotateDefs.h -- Rotate functions +2008-03-24 +Igor Pavlov +Public domain */ + +#ifndef __ROTATEDEFS_H +#define __ROTATEDEFS_H + +#ifdef _MSC_VER + +#include <stdlib.h> +#define rotlFixed(x, n) _rotl((x), (n)) +#define rotrFixed(x, n) _rotr((x), (n)) + +#else + +#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) +#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n)))) + +#endif + +#endif diff --git a/C/Sha256.c b/C/Sha256.c new file mode 100755 index 00000000..f052c0ec --- /dev/null +++ b/C/Sha256.c @@ -0,0 +1,206 @@ +/* Crypto/Sha256.c -- SHA-256 Hash function +2008-03-24 +This code is based on public domain code from Wei Dai's Crypto++ library. +Igor Pavlov +Public domain */ + +#include "Sha256.h" +#include "RotateDefs.h" + +/* define it for speed optimization */ +/* #define _SHA256_UNROLL */ +/* #define _SHA256_UNROLL2 */ + +void Sha256_Init(CSha256 *p) +{ + p->state[0] = 0x6a09e667; + p->state[1] = 0xbb67ae85; + p->state[2] = 0x3c6ef372; + p->state[3] = 0xa54ff53a; + p->state[4] = 0x510e527f; + p->state[5] = 0x9b05688c; + p->state[6] = 0x1f83d9ab; + p->state[7] = 0x5be0cd19; + p->count = 0; +} + +#define S0(x) (rotrFixed(x, 2) ^ rotrFixed(x,13) ^ rotrFixed(x, 22)) +#define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x, 25)) +#define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3)) +#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10)) + +#define blk0(i) (W[i] = data[i]) +#define blk2(i) (W[i&15] += s1(W[(i-2)&15]) + W[(i-7)&15] + s0(W[(i-15)&15])) + +#define Ch(x,y,z) (z^(x&(y^z))) +#define Maj(x,y,z) ((x&y)|(z&(x|y))) + +#define a(i) T[(0-(i))&7] +#define b(i) T[(1-(i))&7] +#define c(i) T[(2-(i))&7] +#define d(i) T[(3-(i))&7] +#define e(i) T[(4-(i))&7] +#define f(i) T[(5-(i))&7] +#define g(i) T[(6-(i))&7] +#define h(i) T[(7-(i))&7] + + +#ifdef _SHA256_UNROLL2 + +#define R(a,b,c,d,e,f,g,h, i) h += S1(e) + Ch(e,f,g) + K[i+j] + (j?blk2(i):blk0(i));\ + d += h; h += S0(a) + Maj(a, b, c) + +#define RX_8(i) \ + R(a,b,c,d,e,f,g,h, i); \ + R(h,a,b,c,d,e,f,g, i+1); \ + R(g,h,a,b,c,d,e,f, i+2); \ + R(f,g,h,a,b,c,d,e, i+3); \ + R(e,f,g,h,a,b,c,d, i+4); \ + R(d,e,f,g,h,a,b,c, i+5); \ + R(c,d,e,f,g,h,a,b, i+6); \ + R(b,c,d,e,f,g,h,a, i+7) + +#else + +#define R(i) h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[i+j] + (j?blk2(i):blk0(i));\ + d(i) += h(i); h(i) += S0(a(i)) + Maj(a(i), b(i), c(i)) + +#ifdef _SHA256_UNROLL + +#define RX_8(i) R(i+0); R(i+1); R(i+2); R(i+3); R(i+4); R(i+5); R(i+6); R(i+7); + +#endif + +#endif + +const UInt32 K[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +static void Sha256_Transform(UInt32 *state, const UInt32 *data) +{ + UInt32 W[16]; + unsigned j; + #ifdef _SHA256_UNROLL2 + UInt32 a,b,c,d,e,f,g,h; + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + #else + UInt32 T[8]; + for (j = 0; j < 8; j++) + T[j] = state[j]; + #endif + + for (j = 0; j < 64; j += 16) + { + #if defined(_SHA256_UNROLL) || defined(_SHA256_UNROLL2) + RX_8(0); RX_8(8); + #else + unsigned i; + for (i = 0; i < 16; i++) { R(i); } + #endif + } + + #ifdef _SHA256_UNROLL2 + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; + #else + for (j = 0; j < 8; j++) + state[j] += T[j]; + #endif + + /* Wipe variables */ + /* memset(W, 0, sizeof(W)); */ + /* memset(T, 0, sizeof(T)); */ +} + +#undef S0 +#undef S1 +#undef s0 +#undef s1 + +static void Sha256_WriteByteBlock(CSha256 *p) +{ + UInt32 data32[16]; + unsigned i; + for (i = 0; i < 16; i++) + data32[i] = + ((UInt32)(p->buffer[i * 4 ]) << 24) + + ((UInt32)(p->buffer[i * 4 + 1]) << 16) + + ((UInt32)(p->buffer[i * 4 + 2]) << 8) + + ((UInt32)(p->buffer[i * 4 + 3])); + Sha256_Transform(p->state, data32); +} + +void Sha256_Update(CSha256 *p, const Byte *data, size_t size) +{ + UInt32 curBufferPos = (UInt32)p->count & 0x3F; + while (size > 0) + { + p->buffer[curBufferPos++] = *data++; + p->count++; + size--; + if (curBufferPos == 64) + { + curBufferPos = 0; + Sha256_WriteByteBlock(p); + } + } +} + +void Sha256_Final(CSha256 *p, Byte *digest) +{ + UInt64 lenInBits = (p->count << 3); + UInt32 curBufferPos = (UInt32)p->count & 0x3F; + unsigned i; + p->buffer[curBufferPos++] = 0x80; + while (curBufferPos != (64 - 8)) + { + curBufferPos &= 0x3F; + if (curBufferPos == 0) + Sha256_WriteByteBlock(p); + p->buffer[curBufferPos++] = 0; + } + for (i = 0; i < 8; i++) + { + p->buffer[curBufferPos++] = (Byte)(lenInBits >> 56); + lenInBits <<= 8; + } + Sha256_WriteByteBlock(p); + + for (i = 0; i < 8; i++) + { + *digest++ = (Byte)(p->state[i] >> 24); + *digest++ = (Byte)(p->state[i] >> 16); + *digest++ = (Byte)(p->state[i] >> 8); + *digest++ = (Byte)(p->state[i]); + } + Sha256_Init(p); +} diff --git a/C/Sha256.h b/C/Sha256.h new file mode 100755 index 00000000..37d6b059 --- /dev/null +++ b/C/Sha256.h @@ -0,0 +1,24 @@ +/* Crypto/Sha256.h -- SHA-256 Hash function +2008-03-24 +Igor Pavlov +Public domain */ + +#ifndef __CRYPTO_SHA256_H +#define __CRYPTO_SHA256_H + +#include "Types.h" + +#define SHA256_DIGEST_SIZE 32 + +typedef struct +{ + UInt32 state[8]; + UInt64 count; + Byte buffer[64]; +} CSha256; + +void Sha256_Init(CSha256 *p); +void Sha256_Update(CSha256 *p, const Byte *data, size_t size); +void Sha256_Final(CSha256 *p, Byte *digest); + +#endif @@ -1,4 +1,7 @@ -/* Sort.c */ +/* Sort.c -- Sort functions +2008-03-13 +Igor Pavlov +Public domain */ #include "Sort.h" @@ -1,7 +1,10 @@ -/* Sort.h */ +/* Sort.h -- Sort functions +2008-03-19 +Igor Pavlov +Public domain */ -#ifndef __7Z_Sort_H -#define __7Z_Sort_H +#ifndef __7Z_SORT_H +#define __7Z_SORT_H #include "Types.h" diff --git a/C/Threads.c b/C/Threads.c index def48175..237f3f90 100755 --- a/C/Threads.c +++ b/C/Threads.c @@ -1,98 +1,101 @@ -/* Threads.c */ +/* Threads.c -- multithreading library +2008-04-04 +Igor Pavlov +Public domain */ #include "Threads.h" #include <process.h> -HRes GetError() +static WRes GetError() { DWORD res = GetLastError(); - return (res) ? (HRes)(res) : SZE_FAIL; + return (res) ? (WRes)(res) : 1; } -HRes BoolToHRes(int v) { return v ? SZ_OK : GetError(); } -HRes BOOLToHRes(BOOL v) { return v ? SZ_OK : GetError(); } +WRes HandleToWRes(HANDLE h) { return (h != 0) ? 0 : GetError(); } +WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); } -HRes MyCloseHandle(HANDLE *h) +static WRes MyCloseHandle(HANDLE *h) { if (*h != NULL) if (!CloseHandle(*h)) return GetError(); *h = NULL; - return SZ_OK; + return 0; } -HRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter) +WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter) { unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */ thread->handle = /* CreateThread(0, 0, startAddress, parameter, 0, &threadId); */ (HANDLE)_beginthreadex(NULL, 0, startAddress, parameter, 0, &threadId); /* maybe we must use errno here, but probably GetLastError() is also OK. */ - return BoolToHRes(thread->handle != 0); + return HandleToWRes(thread->handle); } -HRes WaitObject(HANDLE h) +WRes WaitObject(HANDLE h) { - return (HRes)WaitForSingleObject(h, INFINITE); + return (WRes)WaitForSingleObject(h, INFINITE); } -HRes Thread_Wait(CThread *thread) +WRes Thread_Wait(CThread *thread) { if (thread->handle == NULL) return 1; return WaitObject(thread->handle); } -HRes Thread_Close(CThread *thread) +WRes Thread_Close(CThread *thread) { return MyCloseHandle(&thread->handle); } -HRes Event_Create(CEvent *p, BOOL manualReset, int initialSignaled) +WRes Event_Create(CEvent *p, BOOL manualReset, int initialSignaled) { p->handle = CreateEvent(NULL, manualReset, (initialSignaled ? TRUE : FALSE), NULL); - return BoolToHRes(p->handle != 0); + return HandleToWRes(p->handle); } -HRes ManualResetEvent_Create(CManualResetEvent *p, int initialSignaled) +WRes ManualResetEvent_Create(CManualResetEvent *p, int initialSignaled) { return Event_Create(p, TRUE, initialSignaled); } -HRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) +WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) { return ManualResetEvent_Create(p, 0); } -HRes AutoResetEvent_Create(CAutoResetEvent *p, int initialSignaled) +WRes AutoResetEvent_Create(CAutoResetEvent *p, int initialSignaled) { return Event_Create(p, FALSE, initialSignaled); } -HRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) +WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) { return AutoResetEvent_Create(p, 0); } -HRes Event_Set(CEvent *p) { return BOOLToHRes(SetEvent(p->handle)); } -HRes Event_Reset(CEvent *p) { return BOOLToHRes(ResetEvent(p->handle)); } -HRes Event_Wait(CEvent *p) { return WaitObject(p->handle); } -HRes Event_Close(CEvent *p) { return MyCloseHandle(&p->handle); } +WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(p->handle)); } +WRes Event_Reset(CEvent *p) { return BOOLToWRes(ResetEvent(p->handle)); } +WRes Event_Wait(CEvent *p) { return WaitObject(p->handle); } +WRes Event_Close(CEvent *p) { return MyCloseHandle(&p->handle); } -HRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount) +WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount) { p->handle = CreateSemaphore(NULL, (LONG)initiallyCount, (LONG)maxCount, NULL); - return BoolToHRes(p->handle != 0); + return HandleToWRes(p->handle); } -HRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount) +WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount) { - return BOOLToHRes(ReleaseSemaphore(p->handle, releaseCount, previousCount)); + return BOOLToWRes(ReleaseSemaphore(p->handle, releaseCount, previousCount)); } -HRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount) +WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount) { return Semaphore_Release(p, (LONG)releaseCount, NULL); } -HRes Semaphore_Release1(CSemaphore *p) +WRes Semaphore_Release1(CSemaphore *p) { return Semaphore_ReleaseN(p, 1); } -HRes Semaphore_Wait(CSemaphore *p) { return WaitObject(p->handle); } -HRes Semaphore_Close(CSemaphore *p) { return MyCloseHandle(&p->handle); } +WRes Semaphore_Wait(CSemaphore *p) { return WaitObject(p->handle); } +WRes Semaphore_Close(CSemaphore *p) { return MyCloseHandle(&p->handle); } -HRes CriticalSection_Init(CCriticalSection *p) +WRes CriticalSection_Init(CCriticalSection *p) { /* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */ __try @@ -100,7 +103,7 @@ HRes CriticalSection_Init(CCriticalSection *p) InitializeCriticalSection(p); /* InitializeCriticalSectionAndSpinCount(p, 0); */ } - __except (EXCEPTION_EXECUTE_HANDLER) { return SZE_OUTOFMEMORY; } - return SZ_OK; + __except (EXCEPTION_EXECUTE_HANDLER) { return 1; } + return 0; } diff --git a/C/Threads.h b/C/Threads.h index c024dcc6..03bea106 100755 --- a/C/Threads.h +++ b/C/Threads.h @@ -1,4 +1,7 @@ -/* Threads.h */ +/* Threads.h -- multithreading library +2008-04-11 +Igor Pavlov +Public domain */ #ifndef __7Z_THRESDS_H #define __7Z_THRESDS_H @@ -16,12 +19,14 @@ typedef struct _CThread #define Thread_WasCreated(thread) ((thread)->handle != NULL) typedef unsigned THREAD_FUNC_RET_TYPE; -#define THREAD_FUNC_CALL_TYPE StdCall +#define THREAD_FUNC_CALL_TYPE MY_STD_CALL #define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE -HRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter); -HRes Thread_Wait(CThread *thread); -HRes Thread_Close(CThread *thread); +typedef DWORD WRes; + +WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter); +WRes Thread_Wait(CThread *thread); +WRes Thread_Close(CThread *thread); typedef struct _CEvent { @@ -34,14 +39,14 @@ typedef CEvent CManualResetEvent; #define Event_Construct(event) (event)->handle = NULL #define Event_IsCreated(event) ((event)->handle != NULL) -HRes ManualResetEvent_Create(CManualResetEvent *event, int initialSignaled); -HRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *event); -HRes AutoResetEvent_Create(CAutoResetEvent *event, int initialSignaled); -HRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *event); -HRes Event_Set(CEvent *event); -HRes Event_Reset(CEvent *event); -HRes Event_Wait(CEvent *event); -HRes Event_Close(CEvent *event); +WRes ManualResetEvent_Create(CManualResetEvent *event, int initialSignaled); +WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *event); +WRes AutoResetEvent_Create(CAutoResetEvent *event, int initialSignaled); +WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *event); +WRes Event_Set(CEvent *event); +WRes Event_Reset(CEvent *event); +WRes Event_Wait(CEvent *event); +WRes Event_Close(CEvent *event); typedef struct _CSemaphore @@ -51,16 +56,16 @@ typedef struct _CSemaphore #define Semaphore_Construct(p) (p)->handle = NULL -HRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount); -HRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num); -HRes Semaphore_Release1(CSemaphore *p); -HRes Semaphore_Wait(CSemaphore *p); -HRes Semaphore_Close(CSemaphore *p); +WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount); +WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num); +WRes Semaphore_Release1(CSemaphore *p); +WRes Semaphore_Wait(CSemaphore *p); +WRes Semaphore_Close(CSemaphore *p); typedef CRITICAL_SECTION CCriticalSection; -HRes CriticalSection_Init(CCriticalSection *p); +WRes CriticalSection_Init(CCriticalSection *p); #define CriticalSection_Delete(p) DeleteCriticalSection(p) #define CriticalSection_Enter(p) EnterCriticalSection(p) #define CriticalSection_Leave(p) LeaveCriticalSection(p) @@ -1,100 +1,130 @@ -/* 7zTypes.h */ +/* Types.h -- Basic types +2008-04-11 +Igor Pavlov +Public domain */ + +#ifndef __7Z_TYPES_H +#define __7Z_TYPES_H + +#define SZ_OK 0 + +#define SZ_ERROR_DATA 1 +#define SZ_ERROR_MEM 2 +#define SZ_ERROR_CRC 3 +#define SZ_ERROR_UNSUPPORTED 4 +#define SZ_ERROR_PARAM 5 +#define SZ_ERROR_INPUT_EOF 6 +#define SZ_ERROR_OUTPUT_EOF 7 +#define SZ_ERROR_READ 8 +#define SZ_ERROR_WRITE 9 +#define SZ_ERROR_PROGRESS 10 +#define SZ_ERROR_FAIL 11 +#define SZ_ERROR_THREAD 12 + +#define SZ_ERROR_ARCHIVE 16 +#define SZ_ERROR_NO_ARCHIVE 17 + +typedef int SRes; -#ifndef __C_TYPES_H -#define __C_TYPES_H +#ifndef RINOK +#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } +#endif -#ifndef _7ZIP_BYTE_DEFINED -#define _7ZIP_BYTE_DEFINED typedef unsigned char Byte; -#endif - -#ifndef _7ZIP_UINT16_DEFINED -#define _7ZIP_UINT16_DEFINED +typedef short Int16; typedef unsigned short UInt16; -#endif -#ifndef _7ZIP_UINT32_DEFINED -#define _7ZIP_UINT32_DEFINED #ifdef _LZMA_UINT32_IS_ULONG -typedef unsigned long UInt32; -#else -typedef unsigned int UInt32; -#endif -#endif - -#ifndef _7ZIP_INT32_DEFINED -#define _7ZIP_INT32_DEFINED -#ifdef _LZMA_INT32_IS_ULONG typedef long Int32; +typedef unsigned long UInt32; #else typedef int Int32; +typedef unsigned int UInt32; #endif -#endif /* #define _SZ_NO_INT_64 */ -/* define it your compiler doesn't support long long int */ +/* define it if your compiler doesn't support 64-bit integers */ -#ifndef _7ZIP_UINT64_DEFINED -#define _7ZIP_UINT64_DEFINED #ifdef _SZ_NO_INT_64 + +typedef long Int64; typedef unsigned long UInt64; + #else + #if defined(_MSC_VER) || defined(__BORLANDC__) +typedef __int64 Int64; typedef unsigned __int64 UInt64; #else +typedef long long int Int64; typedef unsigned long long int UInt64; #endif -#endif -#endif - -/* #define _SZ_FILE_SIZE_32 */ -/* You can define _SZ_FILE_SIZE_32, if you don't need support for files larger than 4 GB*/ - -#ifndef CFileSize -#ifdef _SZ_FILE_SIZE_32 -typedef UInt32 CFileSize; -#else -typedef UInt64 CFileSize; #endif -#endif - -#define SZ_RESULT int - -typedef int HRes; -#define RES_OK (0) - -#define SZ_OK (0) -#define SZE_DATA_ERROR (1) -#define SZE_CRC_ERROR (3) -#define SZE_ARCHIVE_ERROR (6) - -#define SZE_OUTOFMEMORY (0x8007000EL) -#define SZE_NOTIMPL (0x80004001L) -#define SZE_FAIL (0x80004005L) -#define SZE_INVALIDARG (0x80070057L) - -#ifndef RINOK -#define RINOK(x) { HRes __result_ = (x); if(__result_ != 0) return __result_; } +#ifdef _LZMA_NO_SYSTEM_SIZE_T +typedef UInt32 SizeT; +#else +#include <stddef.h> +typedef size_t SizeT; #endif typedef int Bool; #define True 1 #define False 0 + #ifdef _MSC_VER -#define StdCall __stdcall + +#if _MSC_VER >= 1300 +#define MY_NO_INLINE __declspec(noinline) #else -#define StdCall +#define MY_NO_INLINE #endif -#if _MSC_VER >= 1300 -#define MY_FAST_CALL __declspec(noinline) __fastcall -#elif defined( _MSC_VER) -#define MY_FAST_CALL __fastcall +#define MY_CDECL __cdecl +#define MY_STD_CALL __stdcall +#define MY_FAST_CALL MY_NO_INLINE __fastcall + #else + +#define MY_CDECL +#define MY_STD_CALL #define MY_FAST_CALL + #endif + +/* The following interfaces use first parameter as pointer to structure */ + +typedef struct +{ + SRes (*Read)(void *p, void *buf, size_t *size); + /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. + (output(*size) < input(*size)) is allowed */ +} ISeqInStream; + +typedef struct +{ + size_t (*Write)(void *p, const void *buf, size_t size); + /* Returns: result - the number of actually written bytes. + (result < size) means error */ +} ISeqOutStream; + +typedef struct +{ + SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); + /* Returns: result. (result != SZ_OK) means break. + Value (UInt64)(Int64)-1 for size means unknown value. */ +} ICompressProgress; + +typedef struct +{ + void *(*Alloc)(void *p, size_t size); + void (*Free)(void *p, void *address); /* address can be 0 */ +} ISzAlloc; + +#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) +#define IAlloc_Free(p, a) (p)->Free((p), a) + #endif |