1 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,138 +0,0 @@ |
1 |
-/* |
|
2 |
- * Copyright (C) 2009 Sourcefire, Inc. |
|
3 |
- * |
|
4 |
- * Authors: aCaB |
|
5 |
- * |
|
6 |
- * This program is free software; you can redistribute it and/or modify |
|
7 |
- * it under the terms of the GNU General Public License version 2 as |
|
8 |
- * published by the Free Software Foundation. |
|
9 |
- * |
|
10 |
- * This program is distributed in the hope that it will be useful, |
|
11 |
- * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 |
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 |
- * GNU General Public License for more details. |
|
14 |
- * |
|
15 |
- * You should have received a copy of the GNU General Public License |
|
16 |
- * along with this program; if not, write to the Free Software |
|
17 |
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
18 |
- * MA 02110-1301, USA. |
|
19 |
- */ |
|
20 |
- |
|
21 |
-/* 7zip scanner */ |
|
22 |
- |
|
23 |
-#if HAVE_CONFIG_H |
|
24 |
-#include "clamav-config.h" |
|
25 |
-#endif |
|
26 |
- |
|
27 |
-#include <stdio.h> |
|
28 |
-#include <sys/types.h> |
|
29 |
-#include <sys/stat.h> |
|
30 |
-#include <fcntl.h> |
|
31 |
- |
|
32 |
-#include "others.h" |
|
33 |
-#include "lzma_iface.h" |
|
34 |
-#include "scanners.h" |
|
35 |
-#include "matcher.h" |
|
36 |
-#include "7z/7zFile.h" |
|
37 |
-#include "7z/7zCrc.h" |
|
38 |
-#include "7z/Archive/7z/7zIn.h" |
|
39 |
-#include "7z/Archive/7z/7zExtract.h" |
|
40 |
- |
|
41 |
-static ISzAlloc allocImp = { __lzma_wrap_alloc, __lzma_wrap_free}, allocTempImp = { __lzma_wrap_alloc, __lzma_wrap_free}; |
|
42 |
- |
|
43 |
-int cli_7unz (int fd, cli_ctx *ctx) { |
|
44 |
- CFileInStream archiveStream; |
|
45 |
- CLookToRead lookStream; |
|
46 |
- CSzArEx db; |
|
47 |
- UInt32 blockIndex = 0xFFFFFFFF; |
|
48 |
- unsigned char *buf = NULL; |
|
49 |
- size_t bufsz = 0; |
|
50 |
- UInt32 i; |
|
51 |
- int dupfd, ret = CL_CLEAN; |
|
52 |
- unsigned int fu=0; |
|
53 |
- |
|
54 |
- if((dupfd = dup(fd)) == -1) { |
|
55 |
- cli_errmsg("cli_7unz: dup() failed\n"); |
|
56 |
- return CL_EDUP; |
|
57 |
- } |
|
58 |
- FileInStream_CreateVTable(&archiveStream); |
|
59 |
- archiveStream.file.file = fdopen(dupfd, "rb"); |
|
60 |
- if(!archiveStream.file.file) { |
|
61 |
- cli_errmsg("cli_7unz: fdopen() failed\n"); |
|
62 |
- return CL_EOPEN; |
|
63 |
- } |
|
64 |
- LookToRead_CreateVTable(&lookStream, False); |
|
65 |
- lookStream.realStream = &archiveStream.s; |
|
66 |
- LookToRead_Init(&lookStream); |
|
67 |
- |
|
68 |
- SzArEx_Init(&db); |
|
69 |
- if(SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp) != SZ_OK) { |
|
70 |
- SzArEx_Free(&db, &allocImp); |
|
71 |
- cli_dbgmsg("cli_7unz: possibly damaged archive\n"); |
|
72 |
- fclose(archiveStream.file.file); |
|
73 |
- return CL_CLEAN; |
|
74 |
- } |
|
75 |
- for (i = 0; i < db.db.NumFiles; i++) { |
|
76 |
- CSzFileItem *f = db.db.Files + i; |
|
77 |
- size_t offset; |
|
78 |
- size_t usize; |
|
79 |
- |
|
80 |
- if(f->IsDir || !f->Size) continue; |
|
81 |
- if(ctx->engine->maxfilesize && f->Size > ctx->engine->maxfilesize) { |
|
82 |
- cli_dbgmsg("cli_7unz: skipping stream due to size limits (%llu vs %llu)\n", (long long)f->Size, (long long)ctx->engine->maxfilesize); |
|
83 |
- continue; |
|
84 |
- } |
|
85 |
- if(cli_matchmeta(ctx, f->Name, 0, f->Size, 0, i + 1, 0, NULL) == CL_VIRUS) { |
|
86 |
- ret = CL_VIRUS; |
|
87 |
- break; |
|
88 |
- } |
|
89 |
- if (ctx->engine->maxfiles && fu>=ctx->engine->maxfiles) { |
|
90 |
- cli_dbgmsg("cli_7unz: Files limit reached (max: %u)\n", ctx->engine->maxfiles); |
|
91 |
- ret=CL_EMAXFILES; |
|
92 |
- break; |
|
93 |
- } |
|
94 |
- cli_dbgmsg("cli_7unz: Extracting file %s\n", f->Name); |
|
95 |
- if(SzAr_Extract(&db, &lookStream.s, i, &blockIndex, &buf, &bufsz, &offset, &usize, &allocImp, &allocTempImp) == SZ_OK) { |
|
96 |
- char *fname; |
|
97 |
- int ofd; |
|
98 |
- |
|
99 |
- if(!usize) { |
|
100 |
- cli_dbgmsg("cli_7unz: stream uncompressed to an empty file\n"); |
|
101 |
- continue; |
|
102 |
- } |
|
103 |
- fu++; |
|
104 |
- if(!(fname = cli_gentemp(ctx->engine->tmpdir))) { |
|
105 |
- ret = CL_EMEM; |
|
106 |
- break; |
|
107 |
- } |
|
108 |
- if((ofd = open(fname, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRUSR|S_IWUSR)) < 0) { |
|
109 |
- cli_errmsg("cli_7unz: failed to create file %s\n", fname); |
|
110 |
- free(fname); |
|
111 |
- ret = CL_ECREAT; |
|
112 |
- break; |
|
113 |
- } |
|
114 |
- if(cli_writen(ofd, buf, usize) <= 0) { |
|
115 |
- close(ofd); |
|
116 |
- if(cli_unlink(fname)) ret = CL_EUNLINK; |
|
117 |
- else ret = CL_EWRITE; |
|
118 |
- free(fname); |
|
119 |
- break; |
|
120 |
- } |
|
121 |
- cli_dbgmsg("cli_7unz: extracted to %s\n", fname); |
|
122 |
- lseek(ofd, 0, SEEK_SET); |
|
123 |
- ret = cli_magic_scandesc(ofd, ctx); |
|
124 |
- close(ofd); |
|
125 |
- if(!ctx->engine->keeptmp) |
|
126 |
- if(cli_unlink(fname)) ret = CL_EUNLINK; |
|
127 |
- free(fname); |
|
128 |
- if(ret == CL_EUNLINK || ret == CL_VIRUS) |
|
129 |
- break; |
|
130 |
- } else { |
|
131 |
- cli_dbgmsg("cli_7unz: decompression failed\n"); |
|
132 |
- } |
|
133 |
- } |
|
134 |
- if(buf) free(buf); |
|
135 |
- SzArEx_Free(&db, &allocImp); |
|
136 |
- fclose(archiveStream.file.file); |
|
137 |
- return ret; |
|
138 |
-} |
139 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,32 +0,0 @@ |
1 |
-/* |
|
2 |
- * Copyright (C) 2009 Sourcefire, Inc. |
|
3 |
- * |
|
4 |
- * Authors: aCaB |
|
5 |
- * |
|
6 |
- * This program is free software; you can redistribute it and/or modify |
|
7 |
- * it under the terms of the GNU General Public License version 2 as |
|
8 |
- * published by the Free Software Foundation. |
|
9 |
- * |
|
10 |
- * This program is distributed in the hope that it will be useful, |
|
11 |
- * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 |
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 |
- * GNU General Public License for more details. |
|
14 |
- * |
|
15 |
- * You should have received a copy of the GNU General Public License |
|
16 |
- * along with this program; if not, write to the Free Software |
|
17 |
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
18 |
- * MA 02110-1301, USA. |
|
19 |
- */ |
|
20 |
- |
|
21 |
-#ifndef __7Z_H |
|
22 |
-#define __7Z_H |
|
23 |
- |
|
24 |
-#if HAVE_CONFIG_H |
|
25 |
-#include "clamav-config.h" |
|
26 |
-#endif |
|
27 |
- |
|
28 |
-#include "others.h" |
|
29 |
- |
|
30 |
-int cli_7unz (int, cli_ctx *); |
|
31 |
- |
|
32 |
-#endif |
33 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,203 @@ |
0 |
+/* 7z.h -- 7z interface |
|
1 |
+2010-03-11 : Igor Pavlov : Public domain */ |
|
2 |
+ |
|
3 |
+#ifndef __7Z_H |
|
4 |
+#define __7Z_H |
|
5 |
+ |
|
6 |
+#include "7zBuf.h" |
|
7 |
+ |
|
8 |
+EXTERN_C_BEGIN |
|
9 |
+ |
|
10 |
+#define k7zStartHeaderSize 0x20 |
|
11 |
+#define k7zSignatureSize 6 |
|
12 |
+extern Byte k7zSignature[k7zSignatureSize]; |
|
13 |
+#define k7zMajorVersion 0 |
|
14 |
+ |
|
15 |
+enum EIdEnum |
|
16 |
+{ |
|
17 |
+ k7zIdEnd, |
|
18 |
+ k7zIdHeader, |
|
19 |
+ k7zIdArchiveProperties, |
|
20 |
+ k7zIdAdditionalStreamsInfo, |
|
21 |
+ k7zIdMainStreamsInfo, |
|
22 |
+ k7zIdFilesInfo, |
|
23 |
+ k7zIdPackInfo, |
|
24 |
+ k7zIdUnpackInfo, |
|
25 |
+ k7zIdSubStreamsInfo, |
|
26 |
+ k7zIdSize, |
|
27 |
+ k7zIdCRC, |
|
28 |
+ k7zIdFolder, |
|
29 |
+ k7zIdCodersUnpackSize, |
|
30 |
+ k7zIdNumUnpackStream, |
|
31 |
+ k7zIdEmptyStream, |
|
32 |
+ k7zIdEmptyFile, |
|
33 |
+ k7zIdAnti, |
|
34 |
+ k7zIdName, |
|
35 |
+ k7zIdCTime, |
|
36 |
+ k7zIdATime, |
|
37 |
+ k7zIdMTime, |
|
38 |
+ k7zIdWinAttributes, |
|
39 |
+ k7zIdComment, |
|
40 |
+ k7zIdEncodedHeader, |
|
41 |
+ k7zIdStartPos, |
|
42 |
+ k7zIdDummy |
|
43 |
+}; |
|
44 |
+ |
|
45 |
+typedef struct |
|
46 |
+{ |
|
47 |
+ UInt32 NumInStreams; |
|
48 |
+ UInt32 NumOutStreams; |
|
49 |
+ UInt64 MethodID; |
|
50 |
+ CBuf Props; |
|
51 |
+} CSzCoderInfo; |
|
52 |
+ |
|
53 |
+void SzCoderInfo_Init(CSzCoderInfo *p); |
|
54 |
+void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc); |
|
55 |
+ |
|
56 |
+typedef struct |
|
57 |
+{ |
|
58 |
+ UInt32 InIndex; |
|
59 |
+ UInt32 OutIndex; |
|
60 |
+} CSzBindPair; |
|
61 |
+ |
|
62 |
+typedef struct |
|
63 |
+{ |
|
64 |
+ CSzCoderInfo *Coders; |
|
65 |
+ CSzBindPair *BindPairs; |
|
66 |
+ UInt32 *PackStreams; |
|
67 |
+ UInt64 *UnpackSizes; |
|
68 |
+ UInt32 NumCoders; |
|
69 |
+ UInt32 NumBindPairs; |
|
70 |
+ UInt32 NumPackStreams; |
|
71 |
+ int UnpackCRCDefined; |
|
72 |
+ UInt32 UnpackCRC; |
|
73 |
+ |
|
74 |
+ UInt32 NumUnpackStreams; |
|
75 |
+} CSzFolder; |
|
76 |
+ |
|
77 |
+void SzFolder_Init(CSzFolder *p); |
|
78 |
+UInt64 SzFolder_GetUnpackSize(CSzFolder *p); |
|
79 |
+int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex); |
|
80 |
+UInt32 SzFolder_GetNumOutStreams(CSzFolder *p); |
|
81 |
+UInt64 SzFolder_GetUnpackSize(CSzFolder *p); |
|
82 |
+ |
|
83 |
+SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes, |
|
84 |
+ ILookInStream *stream, UInt64 startPos, |
|
85 |
+ Byte *outBuffer, size_t outSize, ISzAlloc *allocMain); |
|
86 |
+ |
|
87 |
+typedef struct |
|
88 |
+{ |
|
89 |
+ UInt32 Low; |
|
90 |
+ UInt32 High; |
|
91 |
+} CNtfsFileTime; |
|
92 |
+ |
|
93 |
+typedef struct |
|
94 |
+{ |
|
95 |
+ CNtfsFileTime MTime; |
|
96 |
+ UInt64 Size; |
|
97 |
+ UInt32 Crc; |
|
98 |
+ UInt32 Attrib; |
|
99 |
+ Byte HasStream; |
|
100 |
+ Byte IsDir; |
|
101 |
+ Byte IsAnti; |
|
102 |
+ Byte CrcDefined; |
|
103 |
+ Byte MTimeDefined; |
|
104 |
+ Byte AttribDefined; |
|
105 |
+} CSzFileItem; |
|
106 |
+ |
|
107 |
+void SzFile_Init(CSzFileItem *p); |
|
108 |
+ |
|
109 |
+typedef struct |
|
110 |
+{ |
|
111 |
+ UInt64 *PackSizes; |
|
112 |
+ Byte *PackCRCsDefined; |
|
113 |
+ UInt32 *PackCRCs; |
|
114 |
+ CSzFolder *Folders; |
|
115 |
+ CSzFileItem *Files; |
|
116 |
+ UInt32 NumPackStreams; |
|
117 |
+ UInt32 NumFolders; |
|
118 |
+ UInt32 NumFiles; |
|
119 |
+} CSzAr; |
|
120 |
+ |
|
121 |
+void SzAr_Init(CSzAr *p); |
|
122 |
+void SzAr_Free(CSzAr *p, ISzAlloc *alloc); |
|
123 |
+ |
|
124 |
+ |
|
125 |
+/* |
|
126 |
+ SzExtract extracts file from archive |
|
127 |
+ |
|
128 |
+ *outBuffer must be 0 before first call for each new archive. |
|
129 |
+ |
|
130 |
+ Extracting cache: |
|
131 |
+ If you need to decompress more than one file, you can send |
|
132 |
+ these values from previous call: |
|
133 |
+ *blockIndex, |
|
134 |
+ *outBuffer, |
|
135 |
+ *outBufferSize |
|
136 |
+ You can consider "*outBuffer" as cache of solid block. If your archive is solid, |
|
137 |
+ it will increase decompression speed. |
|
138 |
+ |
|
139 |
+ If you use external function, you can declare these 3 cache variables |
|
140 |
+ (blockIndex, outBuffer, outBufferSize) as static in that external function. |
|
141 |
+ |
|
142 |
+ Free *outBuffer and set *outBuffer to 0, if you want to flush cache. |
|
143 |
+*/ |
|
144 |
+ |
|
145 |
+typedef struct |
|
146 |
+{ |
|
147 |
+ CSzAr db; |
|
148 |
+ |
|
149 |
+ UInt64 startPosAfterHeader; |
|
150 |
+ UInt64 dataPos; |
|
151 |
+ |
|
152 |
+ UInt32 *FolderStartPackStreamIndex; |
|
153 |
+ UInt64 *PackStreamStartPositions; |
|
154 |
+ UInt32 *FolderStartFileIndex; |
|
155 |
+ UInt32 *FileIndexToFolderIndexMap; |
|
156 |
+ |
|
157 |
+ size_t *FileNameOffsets; /* in 2-byte steps */ |
|
158 |
+ CBuf FileNames; /* UTF-16-LE */ |
|
159 |
+} CSzArEx; |
|
160 |
+ |
|
161 |
+void SzArEx_Init(CSzArEx *p); |
|
162 |
+void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc); |
|
163 |
+UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder); |
|
164 |
+int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize); |
|
165 |
+ |
|
166 |
+/* |
|
167 |
+if dest == NULL, the return value specifies the required size of the buffer, |
|
168 |
+ in 16-bit characters, including the null-terminating character. |
|
169 |
+if dest != NULL, the return value specifies the number of 16-bit characters that |
|
170 |
+ are written to the dest, including the null-terminating character. */ |
|
171 |
+ |
|
172 |
+size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest); |
|
173 |
+ |
|
174 |
+SRes SzArEx_Extract( |
|
175 |
+ const CSzArEx *db, |
|
176 |
+ ILookInStream *inStream, |
|
177 |
+ UInt32 fileIndex, /* index of file */ |
|
178 |
+ UInt32 *blockIndex, /* index of solid block */ |
|
179 |
+ Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ |
|
180 |
+ size_t *outBufferSize, /* buffer size for output buffer */ |
|
181 |
+ size_t *offset, /* offset of stream for required file in *outBuffer */ |
|
182 |
+ size_t *outSizeProcessed, /* size of file in *outBuffer */ |
|
183 |
+ ISzAlloc *allocMain, |
|
184 |
+ ISzAlloc *allocTemp); |
|
185 |
+ |
|
186 |
+ |
|
187 |
+/* |
|
188 |
+SzArEx_Open Errors: |
|
189 |
+SZ_ERROR_NO_ARCHIVE |
|
190 |
+SZ_ERROR_ARCHIVE |
|
191 |
+SZ_ERROR_UNSUPPORTED |
|
192 |
+SZ_ERROR_MEM |
|
193 |
+SZ_ERROR_CRC |
|
194 |
+SZ_ERROR_INPUT_EOF |
|
195 |
+SZ_ERROR_FAIL |
|
196 |
+*/ |
|
197 |
+ |
|
198 |
+SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp); |
|
199 |
+ |
|
200 |
+EXTERN_C_END |
|
201 |
+ |
|
202 |
+#endif |
0 | 203 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,76 @@ |
0 |
+/* 7zAlloc.c -- Allocation functions |
|
1 |
+2010-10-29 : Igor Pavlov : Public domain */ |
|
2 |
+ |
|
3 |
+#include "7zAlloc.h" |
|
4 |
+ |
|
5 |
+/* #define _SZ_ALLOC_DEBUG */ |
|
6 |
+/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */ |
|
7 |
+ |
|
8 |
+#ifdef _SZ_ALLOC_DEBUG |
|
9 |
+ |
|
10 |
+#ifdef _WIN32 |
|
11 |
+#include <windows.h> |
|
12 |
+#endif |
|
13 |
+ |
|
14 |
+#include <stdio.h> |
|
15 |
+int g_allocCount = 0; |
|
16 |
+int g_allocCountTemp = 0; |
|
17 |
+ |
|
18 |
+#endif |
|
19 |
+ |
|
20 |
+void *SzAlloc(void *p, size_t size) |
|
21 |
+{ |
|
22 |
+ p = p; |
|
23 |
+ if (size == 0) |
|
24 |
+ return 0; |
|
25 |
+ #ifdef _SZ_ALLOC_DEBUG |
|
26 |
+ fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount); |
|
27 |
+ g_allocCount++; |
|
28 |
+ #endif |
|
29 |
+ return malloc(size); |
|
30 |
+} |
|
31 |
+ |
|
32 |
+void SzFree(void *p, void *address) |
|
33 |
+{ |
|
34 |
+ p = p; |
|
35 |
+ #ifdef _SZ_ALLOC_DEBUG |
|
36 |
+ if (address != 0) |
|
37 |
+ { |
|
38 |
+ g_allocCount--; |
|
39 |
+ fprintf(stderr, "\nFree; count = %10d", g_allocCount); |
|
40 |
+ } |
|
41 |
+ #endif |
|
42 |
+ free(address); |
|
43 |
+} |
|
44 |
+ |
|
45 |
+void *SzAllocTemp(void *p, size_t size) |
|
46 |
+{ |
|
47 |
+ p = p; |
|
48 |
+ if (size == 0) |
|
49 |
+ return 0; |
|
50 |
+ #ifdef _SZ_ALLOC_DEBUG |
|
51 |
+ fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp); |
|
52 |
+ g_allocCountTemp++; |
|
53 |
+ #ifdef _WIN32 |
|
54 |
+ return HeapAlloc(GetProcessHeap(), 0, size); |
|
55 |
+ #endif |
|
56 |
+ #endif |
|
57 |
+ return malloc(size); |
|
58 |
+} |
|
59 |
+ |
|
60 |
+void SzFreeTemp(void *p, void *address) |
|
61 |
+{ |
|
62 |
+ p = p; |
|
63 |
+ #ifdef _SZ_ALLOC_DEBUG |
|
64 |
+ if (address != 0) |
|
65 |
+ { |
|
66 |
+ g_allocCountTemp--; |
|
67 |
+ fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp); |
|
68 |
+ } |
|
69 |
+ #ifdef _WIN32 |
|
70 |
+ HeapFree(GetProcessHeap(), 0, address); |
|
71 |
+ return; |
|
72 |
+ #endif |
|
73 |
+ #endif |
|
74 |
+ free(address); |
|
75 |
+} |
0 | 76 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,15 @@ |
0 |
+/* 7zAlloc.h -- Allocation functions |
|
1 |
+2010-10-29 : Igor Pavlov : Public domain */ |
|
2 |
+ |
|
3 |
+#ifndef __7Z_ALLOC_H |
|
4 |
+#define __7Z_ALLOC_H |
|
5 |
+ |
|
6 |
+#include <stdlib.h> |
|
7 |
+ |
|
8 |
+void *SzAlloc(void *p, size_t size); |
|
9 |
+void SzFree(void *p, void *address); |
|
10 |
+ |
|
11 |
+void *SzAllocTemp(void *p, size_t size); |
|
12 |
+void SzFreeTemp(void *p, void *address); |
|
13 |
+ |
|
14 |
+#endif |
... | ... |
@@ -1,36 +1,36 @@ |
1 |
-/* 7zBuf.c -- Byte Buffer |
|
2 |
-2008-03-28 |
|
3 |
-Igor Pavlov |
|
4 |
-Public domain */ |
|
5 |
- |
|
6 |
-#include "7zBuf.h" |
|
7 |
- |
|
8 |
-void Buf_Init(CBuf *p) |
|
9 |
-{ |
|
10 |
- p->data = 0; |
|
11 |
- p->size = 0; |
|
12 |
-} |
|
13 |
- |
|
14 |
-int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc) |
|
15 |
-{ |
|
16 |
- p->size = 0; |
|
17 |
- if (size == 0) |
|
18 |
- { |
|
19 |
- p->data = 0; |
|
20 |
- return 1; |
|
21 |
- } |
|
22 |
- p->data = (Byte *)alloc->Alloc(alloc, size); |
|
23 |
- if (p->data != 0) |
|
24 |
- { |
|
25 |
- p->size = size; |
|
26 |
- return 1; |
|
27 |
- } |
|
28 |
- return 0; |
|
29 |
-} |
|
30 |
- |
|
31 |
-void Buf_Free(CBuf *p, ISzAlloc *alloc) |
|
32 |
-{ |
|
33 |
- alloc->Free(alloc, p->data); |
|
34 |
- p->data = 0; |
|
35 |
- p->size = 0; |
|
36 |
-} |
|
1 |
+/* 7zBuf.c -- Byte Buffer |
|
2 |
+2008-03-28 |
|
3 |
+Igor Pavlov |
|
4 |
+Public domain */ |
|
5 |
+ |
|
6 |
+#include "7zBuf.h" |
|
7 |
+ |
|
8 |
+void Buf_Init(CBuf *p) |
|
9 |
+{ |
|
10 |
+ p->data = 0; |
|
11 |
+ p->size = 0; |
|
12 |
+} |
|
13 |
+ |
|
14 |
+int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc) |
|
15 |
+{ |
|
16 |
+ p->size = 0; |
|
17 |
+ if (size == 0) |
|
18 |
+ { |
|
19 |
+ p->data = 0; |
|
20 |
+ return 1; |
|
21 |
+ } |
|
22 |
+ p->data = (Byte *)alloc->Alloc(alloc, size); |
|
23 |
+ if (p->data != 0) |
|
24 |
+ { |
|
25 |
+ p->size = size; |
|
26 |
+ return 1; |
|
27 |
+ } |
|
28 |
+ return 0; |
|
29 |
+} |
|
30 |
+ |
|
31 |
+void Buf_Free(CBuf *p, ISzAlloc *alloc) |
|
32 |
+{ |
|
33 |
+ alloc->Free(alloc, p->data); |
|
34 |
+ p->data = 0; |
|
35 |
+ p->size = 0; |
|
36 |
+} |
... | ... |
@@ -1,31 +1,39 @@ |
1 |
-/* 7zBuf.h -- Byte Buffer |
|
2 |
-2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#ifndef __7Z_BUF_H |
|
5 |
-#define __7Z_BUF_H |
|
6 |
- |
|
7 |
-#include "Types.h" |
|
8 |
- |
|
9 |
-typedef struct |
|
10 |
-{ |
|
11 |
- Byte *data; |
|
12 |
- size_t size; |
|
13 |
-} CBuf; |
|
14 |
- |
|
15 |
-void Buf_Init(CBuf *p); |
|
16 |
-int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc); |
|
17 |
-void Buf_Free(CBuf *p, ISzAlloc *alloc); |
|
18 |
- |
|
19 |
-typedef struct |
|
20 |
-{ |
|
21 |
- Byte *data; |
|
22 |
- size_t size; |
|
23 |
- size_t pos; |
|
24 |
-} CDynBuf; |
|
25 |
- |
|
26 |
-void DynBuf_Construct(CDynBuf *p); |
|
27 |
-void DynBuf_SeekToBeg(CDynBuf *p); |
|
28 |
-int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc); |
|
29 |
-void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc); |
|
30 |
- |
|
31 |
-#endif |
|
1 |
+/* 7zBuf.h -- Byte Buffer |
|
2 |
+2009-02-07 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#ifndef __7Z_BUF_H |
|
5 |
+#define __7Z_BUF_H |
|
6 |
+ |
|
7 |
+#include "Types.h" |
|
8 |
+ |
|
9 |
+#ifdef __cplusplus |
|
10 |
+extern "C" { |
|
11 |
+#endif |
|
12 |
+ |
|
13 |
+typedef struct |
|
14 |
+{ |
|
15 |
+ Byte *data; |
|
16 |
+ size_t size; |
|
17 |
+} CBuf; |
|
18 |
+ |
|
19 |
+void Buf_Init(CBuf *p); |
|
20 |
+int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc); |
|
21 |
+void Buf_Free(CBuf *p, ISzAlloc *alloc); |
|
22 |
+ |
|
23 |
+typedef struct |
|
24 |
+{ |
|
25 |
+ Byte *data; |
|
26 |
+ size_t size; |
|
27 |
+ size_t pos; |
|
28 |
+} CDynBuf; |
|
29 |
+ |
|
30 |
+void DynBuf_Construct(CDynBuf *p); |
|
31 |
+void DynBuf_SeekToBeg(CDynBuf *p); |
|
32 |
+int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc); |
|
33 |
+void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc); |
|
34 |
+ |
|
35 |
+#ifdef __cplusplus |
|
36 |
+} |
|
37 |
+#endif |
|
38 |
+ |
|
39 |
+#endif |
32 | 40 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,45 @@ |
0 |
+/* 7zBuf2.c -- Byte Buffer |
|
1 |
+2008-10-04 : Igor Pavlov : Public domain */ |
|
2 |
+ |
|
3 |
+#include <string.h> |
|
4 |
+#include "7zBuf.h" |
|
5 |
+ |
|
6 |
+void DynBuf_Construct(CDynBuf *p) |
|
7 |
+{ |
|
8 |
+ p->data = 0; |
|
9 |
+ p->size = 0; |
|
10 |
+ p->pos = 0; |
|
11 |
+} |
|
12 |
+ |
|
13 |
+void DynBuf_SeekToBeg(CDynBuf *p) |
|
14 |
+{ |
|
15 |
+ p->pos = 0; |
|
16 |
+} |
|
17 |
+ |
|
18 |
+int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc) |
|
19 |
+{ |
|
20 |
+ if (size > p->size - p->pos) |
|
21 |
+ { |
|
22 |
+ size_t newSize = p->pos + size; |
|
23 |
+ Byte *data; |
|
24 |
+ newSize += newSize / 4; |
|
25 |
+ data = (Byte *)alloc->Alloc(alloc, newSize); |
|
26 |
+ if (data == 0) |
|
27 |
+ return 0; |
|
28 |
+ p->size = newSize; |
|
29 |
+ memcpy(data, p->data, p->pos); |
|
30 |
+ alloc->Free(alloc, p->data); |
|
31 |
+ p->data = data; |
|
32 |
+ } |
|
33 |
+ memcpy(p->data + p->pos, buf, size); |
|
34 |
+ p->pos += size; |
|
35 |
+ return 1; |
|
36 |
+} |
|
37 |
+ |
|
38 |
+void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc) |
|
39 |
+{ |
|
40 |
+ alloc->Free(alloc, p->data); |
|
41 |
+ p->data = 0; |
|
42 |
+ p->size = 0; |
|
43 |
+ p->pos = 0; |
|
44 |
+} |
... | ... |
@@ -1,24 +1,23 @@ |
1 |
-/* 7zCrc.c -- CRC32 calculation |
|
2 |
-2008-08-05 |
|
3 |
-Igor Pavlov |
|
4 |
-Public domain */ |
|
5 |
- |
|
6 |
-#include "7zCrc.h" |
|
7 |
- |
|
8 |
-#define kCrcPoly 0xEDB88320 |
|
9 |
-/* aCaB - Make the table a global const */ |
|
10 |
-const UInt32 g_CrcTable[256] = { 0, 0x77073096, 0xee0e612c, 0x990951ba, 0x76dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0xedb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x9b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x1db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x6b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0xf00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x86d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x3b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x4db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0xd6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0xa00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x26d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x5005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0xcb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0xbdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; |
|
11 |
- |
|
12 |
- |
|
13 |
-UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) |
|
14 |
-{ |
|
15 |
- const Byte *p = (const Byte *)data; |
|
16 |
- for (; size > 0 ; size--, p++) |
|
17 |
- v = CRC_UPDATE_BYTE(v, *p); |
|
18 |
- return v; |
|
19 |
-} |
|
20 |
- |
|
21 |
-UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size) |
|
22 |
-{ |
|
23 |
- return CrcUpdate(CRC_INIT_VAL, data, size) ^ 0xFFFFFFFF; |
|
24 |
-} |
|
1 |
+/* 7zCrc.c -- CRC32 calculation |
|
2 |
+2009-11-23 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#include "7zCrc.h" |
|
5 |
+#include "CpuArch.h" |
|
6 |
+ |
|
7 |
+const UInt32 g_CrcTable[256] = { 0x0, 0x77073096, 0xee0e612c, 0x990951ba, 0x76dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0xedb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x9b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x1db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x6b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0xf00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x86d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x3b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x4db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0xd6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0xa00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x26d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x5005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0xcb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0xbdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; |
|
8 |
+ |
|
9 |
+ |
|
10 |
+#define CRC_UPDATE_BYTE_2(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) |
|
11 |
+ |
|
12 |
+UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) |
|
13 |
+{ |
|
14 |
+ const Byte *p = (const Byte *)data; |
|
15 |
+ for (; size > 0; size--, p++) |
|
16 |
+ v = CRC_UPDATE_BYTE_2(v, *p); |
|
17 |
+ return v; |
|
18 |
+} |
|
19 |
+ |
|
20 |
+UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size) |
|
21 |
+{ |
|
22 |
+ return CrcUpdate(CRC_INIT_VAL, data, size) ^ CRC_INIT_VAL; |
|
23 |
+} |
... | ... |
@@ -1,24 +1,18 @@ |
1 |
-/* 7zCrc.h -- CRC32 calculation |
|
2 |
-2008-03-13 |
|
3 |
-Igor Pavlov |
|
4 |
-Public domain */ |
|
5 |
- |
|
6 |
-#ifndef __7Z_CRC_H |
|
7 |
-#define __7Z_CRC_H |
|
8 |
- |
|
9 |
-#include <stddef.h> |
|
10 |
- |
|
11 |
-#include "Types.h" |
|
12 |
- |
|
13 |
-extern const UInt32 g_CrcTable[]; |
|
14 |
- |
|
15 |
-void MY_FAST_CALL CrcGenerateTable(void); |
|
16 |
- |
|
17 |
-#define CRC_INIT_VAL 0xFFFFFFFF |
|
18 |
-#define CRC_GET_DIGEST(crc) ((crc) ^ 0xFFFFFFFF) |
|
19 |
-#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) |
|
20 |
- |
|
21 |
-UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size); |
|
22 |
-UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size); |
|
23 |
- |
|
24 |
-#endif |
|
1 |
+/* 7zCrc.h -- CRC32 calculation |
|
2 |
+2009-11-21 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#ifndef __7Z_CRC_H |
|
5 |
+#define __7Z_CRC_H |
|
6 |
+ |
|
7 |
+#include "Types.h" |
|
8 |
+ |
|
9 |
+EXTERN_C_BEGIN |
|
10 |
+ |
|
11 |
+#define CRC_INIT_VAL 0xFFFFFFFF |
|
12 |
+ |
|
13 |
+UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size); |
|
14 |
+UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size); |
|
15 |
+ |
|
16 |
+EXTERN_C_END |
|
17 |
+ |
|
18 |
+#endif |
25 | 19 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,470 @@ |
0 |
+/* 7zDec.c -- Decoding from 7z folder |
|
1 |
+2010-11-02 : Igor Pavlov : Public domain */ |
|
2 |
+ |
|
3 |
+#include <string.h> |
|
4 |
+ |
|
5 |
+#define _7ZIP_PPMD_SUPPPORT |
|
6 |
+ |
|
7 |
+#include "7z.h" |
|
8 |
+ |
|
9 |
+#include "Bcj2.h" |
|
10 |
+#include "Bra.h" |
|
11 |
+#include "CpuArch.h" |
|
12 |
+#include "LzmaDec.h" |
|
13 |
+#include "Lzma2Dec.h" |
|
14 |
+#ifdef _7ZIP_PPMD_SUPPPORT |
|
15 |
+#include "Ppmd7.h" |
|
16 |
+#endif |
|
17 |
+ |
|
18 |
+#define k_Copy 0 |
|
19 |
+#define k_LZMA2 0x21 |
|
20 |
+#define k_LZMA 0x30101 |
|
21 |
+#define k_BCJ 0x03030103 |
|
22 |
+#define k_PPC 0x03030205 |
|
23 |
+#define k_ARM 0x03030501 |
|
24 |
+#define k_ARMT 0x03030701 |
|
25 |
+#define k_SPARC 0x03030805 |
|
26 |
+#define k_BCJ2 0x0303011B |
|
27 |
+ |
|
28 |
+#ifdef _7ZIP_PPMD_SUPPPORT |
|
29 |
+ |
|
30 |
+#define k_PPMD 0x30401 |
|
31 |
+ |
|
32 |
+typedef struct |
|
33 |
+{ |
|
34 |
+ IByteIn p; |
|
35 |
+ const Byte *cur; |
|
36 |
+ const Byte *end; |
|
37 |
+ const Byte *begin; |
|
38 |
+ UInt64 processed; |
|
39 |
+ Bool extra; |
|
40 |
+ SRes res; |
|
41 |
+ ILookInStream *inStream; |
|
42 |
+} CByteInToLook; |
|
43 |
+ |
|
44 |
+static Byte ReadByte(void *pp) |
|
45 |
+{ |
|
46 |
+ CByteInToLook *p = (CByteInToLook *)pp; |
|
47 |
+ if (p->cur != p->end) |
|
48 |
+ return *p->cur++; |
|
49 |
+ if (p->res == SZ_OK) |
|
50 |
+ { |
|
51 |
+ size_t size = p->cur - p->begin; |
|
52 |
+ p->processed += size; |
|
53 |
+ p->res = p->inStream->Skip(p->inStream, size); |
|
54 |
+ size = (1 << 25); |
|
55 |
+ p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size); |
|
56 |
+ p->cur = p->begin; |
|
57 |
+ p->end = p->begin + size; |
|
58 |
+ if (size != 0) |
|
59 |
+ return *p->cur++;; |
|
60 |
+ } |
|
61 |
+ p->extra = True; |
|
62 |
+ return 0; |
|
63 |
+} |
|
64 |
+ |
|
65 |
+static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, |
|
66 |
+ Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) |
|
67 |
+{ |
|
68 |
+ CPpmd7 ppmd; |
|
69 |
+ CByteInToLook s; |
|
70 |
+ SRes res = SZ_OK; |
|
71 |
+ |
|
72 |
+ s.p.Read = ReadByte; |
|
73 |
+ s.inStream = inStream; |
|
74 |
+ s.begin = s.end = s.cur = NULL; |
|
75 |
+ s.extra = False; |
|
76 |
+ s.res = SZ_OK; |
|
77 |
+ s.processed = 0; |
|
78 |
+ |
|
79 |
+ if (coder->Props.size != 5) |
|
80 |
+ return SZ_ERROR_UNSUPPORTED; |
|
81 |
+ |
|
82 |
+ { |
|
83 |
+ unsigned order = coder->Props.data[0]; |
|
84 |
+ UInt32 memSize = GetUi32(coder->Props.data + 1); |
|
85 |
+ if (order < PPMD7_MIN_ORDER || |
|
86 |
+ order > PPMD7_MAX_ORDER || |
|
87 |
+ memSize < PPMD7_MIN_MEM_SIZE || |
|
88 |
+ memSize > PPMD7_MAX_MEM_SIZE) |
|
89 |
+ return SZ_ERROR_UNSUPPORTED; |
|
90 |
+ Ppmd7_Construct(&ppmd); |
|
91 |
+ if (!Ppmd7_Alloc(&ppmd, memSize, allocMain)) |
|
92 |
+ return SZ_ERROR_MEM; |
|
93 |
+ Ppmd7_Init(&ppmd, order); |
|
94 |
+ } |
|
95 |
+ { |
|
96 |
+ CPpmd7z_RangeDec rc; |
|
97 |
+ Ppmd7z_RangeDec_CreateVTable(&rc); |
|
98 |
+ rc.Stream = &s.p; |
|
99 |
+ if (!Ppmd7z_RangeDec_Init(&rc)) |
|
100 |
+ res = SZ_ERROR_DATA; |
|
101 |
+ else if (s.extra) |
|
102 |
+ res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA); |
|
103 |
+ else |
|
104 |
+ { |
|
105 |
+ SizeT i; |
|
106 |
+ for (i = 0; i < outSize; i++) |
|
107 |
+ { |
|
108 |
+ int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p); |
|
109 |
+ if (s.extra || sym < 0) |
|
110 |
+ break; |
|
111 |
+ outBuffer[i] = (Byte)sym; |
|
112 |
+ } |
|
113 |
+ if (i != outSize) |
|
114 |
+ res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA); |
|
115 |
+ else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc)) |
|
116 |
+ res = SZ_ERROR_DATA; |
|
117 |
+ } |
|
118 |
+ } |
|
119 |
+ Ppmd7_Free(&ppmd, allocMain); |
|
120 |
+ return res; |
|
121 |
+} |
|
122 |
+ |
|
123 |
+#endif |
|
124 |
+ |
|
125 |
+ |
|
126 |
+static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, |
|
127 |
+ Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) |
|
128 |
+{ |
|
129 |
+ CLzmaDec state; |
|
130 |
+ SRes res = SZ_OK; |
|
131 |
+ |
|
132 |
+ LzmaDec_Construct(&state); |
|
133 |
+ RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain)); |
|
134 |
+ state.dic = outBuffer; |
|
135 |
+ state.dicBufSize = outSize; |
|
136 |
+ LzmaDec_Init(&state); |
|
137 |
+ |
|
138 |
+ for (;;) |
|
139 |
+ { |
|
140 |
+ Byte *inBuf = NULL; |
|
141 |
+ size_t lookahead = (1 << 18); |
|
142 |
+ if (lookahead > inSize) |
|
143 |
+ lookahead = (size_t)inSize; |
|
144 |
+ res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead); |
|
145 |
+ if (res != SZ_OK) |
|
146 |
+ break; |
|
147 |
+ |
|
148 |
+ { |
|
149 |
+ SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos; |
|
150 |
+ ELzmaStatus status; |
|
151 |
+ res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); |
|
152 |
+ lookahead -= inProcessed; |
|
153 |
+ inSize -= inProcessed; |
|
154 |
+ if (res != SZ_OK) |
|
155 |
+ break; |
|
156 |
+ if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos)) |
|
157 |
+ { |
|
158 |
+ if (state.dicBufSize != outSize || lookahead != 0 || |
|
159 |
+ (status != LZMA_STATUS_FINISHED_WITH_MARK && |
|
160 |
+ status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) |
|
161 |
+ res = SZ_ERROR_DATA; |
|
162 |
+ break; |
|
163 |
+ } |
|
164 |
+ res = inStream->Skip((void *)inStream, inProcessed); |
|
165 |
+ if (res != SZ_OK) |
|
166 |
+ break; |
|
167 |
+ } |
|
168 |
+ } |
|
169 |
+ |
|
170 |
+ LzmaDec_FreeProbs(&state, allocMain); |
|
171 |
+ return res; |
|
172 |
+} |
|
173 |
+ |
|
174 |
+static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, |
|
175 |
+ Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) |
|
176 |
+{ |
|
177 |
+ CLzma2Dec state; |
|
178 |
+ SRes res = SZ_OK; |
|
179 |
+ |
|
180 |
+ Lzma2Dec_Construct(&state); |
|
181 |
+ if (coder->Props.size != 1) |
|
182 |
+ return SZ_ERROR_DATA; |
|
183 |
+ RINOK(Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain)); |
|
184 |
+ state.decoder.dic = outBuffer; |
|
185 |
+ state.decoder.dicBufSize = outSize; |
|
186 |
+ Lzma2Dec_Init(&state); |
|
187 |
+ |
|
188 |
+ for (;;) |
|
189 |
+ { |
|
190 |
+ Byte *inBuf = NULL; |
|
191 |
+ size_t lookahead = (1 << 18); |
|
192 |
+ if (lookahead > inSize) |
|
193 |
+ lookahead = (size_t)inSize; |
|
194 |
+ res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead); |
|
195 |
+ if (res != SZ_OK) |
|
196 |
+ break; |
|
197 |
+ |
|
198 |
+ { |
|
199 |
+ SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos; |
|
200 |
+ ELzmaStatus status; |
|
201 |
+ res = Lzma2Dec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); |
|
202 |
+ lookahead -= inProcessed; |
|
203 |
+ inSize -= inProcessed; |
|
204 |
+ if (res != SZ_OK) |
|
205 |
+ break; |
|
206 |
+ if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos)) |
|
207 |
+ { |
|
208 |
+ if (state.decoder.dicBufSize != outSize || lookahead != 0 || |
|
209 |
+ (status != LZMA_STATUS_FINISHED_WITH_MARK)) |
|
210 |
+ res = SZ_ERROR_DATA; |
|
211 |
+ break; |
|
212 |
+ } |
|
213 |
+ res = inStream->Skip((void *)inStream, inProcessed); |
|
214 |
+ if (res != SZ_OK) |
|
215 |
+ break; |
|
216 |
+ } |
|
217 |
+ } |
|
218 |
+ |
|
219 |
+ Lzma2Dec_FreeProbs(&state, allocMain); |
|
220 |
+ return res; |
|
221 |
+} |
|
222 |
+ |
|
223 |
+static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer) |
|
224 |
+{ |
|
225 |
+ while (inSize > 0) |
|
226 |
+ { |
|
227 |
+ void *inBuf; |
|
228 |
+ size_t curSize = (1 << 18); |
|
229 |
+ if (curSize > inSize) |
|
230 |
+ curSize = (size_t)inSize; |
|
231 |
+ RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize)); |
|
232 |
+ if (curSize == 0) |
|
233 |
+ return SZ_ERROR_INPUT_EOF; |
|
234 |
+ memcpy(outBuffer, inBuf, curSize); |
|
235 |
+ outBuffer += curSize; |
|
236 |
+ inSize -= curSize; |
|
237 |
+ RINOK(inStream->Skip((void *)inStream, curSize)); |
|
238 |
+ } |
|
239 |
+ return SZ_OK; |
|
240 |
+} |
|
241 |
+ |
|
242 |
+static Bool IS_MAIN_METHOD(UInt32 m) |
|
243 |
+{ |
|
244 |
+ switch(m) |
|
245 |
+ { |
|
246 |
+ case k_Copy: |
|
247 |
+ case k_LZMA: |
|
248 |
+ case k_LZMA2: |
|
249 |
+ #ifdef _7ZIP_PPMD_SUPPPORT |
|
250 |
+ case k_PPMD: |
|
251 |
+ #endif |
|
252 |
+ return True; |
|
253 |
+ } |
|
254 |
+ return False; |
|
255 |
+} |
|
256 |
+ |
|
257 |
+static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c) |
|
258 |
+{ |
|
259 |
+ return |
|
260 |
+ c->NumInStreams == 1 && |
|
261 |
+ c->NumOutStreams == 1 && |
|
262 |
+ c->MethodID <= (UInt32)0xFFFFFFFF && |
|
263 |
+ IS_MAIN_METHOD((UInt32)c->MethodID); |
|
264 |
+} |
|
265 |
+ |
|
266 |
+#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1) |
|
267 |
+ |
|
268 |
+static SRes CheckSupportedFolder(const CSzFolder *f) |
|
269 |
+{ |
|
270 |
+ if (f->NumCoders < 1 || f->NumCoders > 4) |
|
271 |
+ return SZ_ERROR_UNSUPPORTED; |
|
272 |
+ if (!IS_SUPPORTED_CODER(&f->Coders[0])) |
|
273 |
+ return SZ_ERROR_UNSUPPORTED; |
|
274 |
+ if (f->NumCoders == 1) |
|
275 |
+ { |
|
276 |
+ if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0) |
|
277 |
+ return SZ_ERROR_UNSUPPORTED; |
|
278 |
+ return SZ_OK; |
|
279 |
+ } |
|
280 |
+ if (f->NumCoders == 2) |
|
281 |
+ { |
|
282 |
+ CSzCoderInfo *c = &f->Coders[1]; |
|
283 |
+ if (c->MethodID > (UInt32)0xFFFFFFFF || |
|
284 |
+ c->NumInStreams != 1 || |
|
285 |
+ c->NumOutStreams != 1 || |
|
286 |
+ f->NumPackStreams != 1 || |
|
287 |
+ f->PackStreams[0] != 0 || |
|
288 |
+ f->NumBindPairs != 1 || |
|
289 |
+ f->BindPairs[0].InIndex != 1 || |
|
290 |
+ f->BindPairs[0].OutIndex != 0) |
|
291 |
+ return SZ_ERROR_UNSUPPORTED; |
|
292 |
+ switch ((UInt32)c->MethodID) |
|
293 |
+ { |
|
294 |
+ case k_BCJ: |
|
295 |
+ case k_ARM: |
|
296 |
+ break; |
|
297 |
+ default: |
|
298 |
+ return SZ_ERROR_UNSUPPORTED; |
|
299 |
+ } |
|
300 |
+ return SZ_OK; |
|
301 |
+ } |
|
302 |
+ if (f->NumCoders == 4) |
|
303 |
+ { |
|
304 |
+ if (!IS_SUPPORTED_CODER(&f->Coders[1]) || |
|
305 |
+ !IS_SUPPORTED_CODER(&f->Coders[2]) || |
|
306 |
+ !IS_BCJ2(&f->Coders[3])) |
|
307 |
+ return SZ_ERROR_UNSUPPORTED; |
|
308 |
+ if (f->NumPackStreams != 4 || |
|
309 |
+ f->PackStreams[0] != 2 || |
|
310 |
+ f->PackStreams[1] != 6 || |
|
311 |
+ f->PackStreams[2] != 1 || |
|
312 |
+ f->PackStreams[3] != 0 || |
|
313 |
+ f->NumBindPairs != 3 || |
|
314 |
+ f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 || |
|
315 |
+ f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 || |
|
316 |
+ f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2) |
|
317 |
+ return SZ_ERROR_UNSUPPORTED; |
|
318 |
+ return SZ_OK; |
|
319 |
+ } |
|
320 |
+ return SZ_ERROR_UNSUPPORTED; |
|
321 |
+} |
|
322 |
+ |
|
323 |
+static UInt64 GetSum(const UInt64 *values, UInt32 index) |
|
324 |
+{ |
|
325 |
+ UInt64 sum = 0; |
|
326 |
+ UInt32 i; |
|
327 |
+ for (i = 0; i < index; i++) |
|
328 |
+ sum += values[i]; |
|
329 |
+ return sum; |
|
330 |
+} |
|
331 |
+ |
|
332 |
+#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break; |
|
333 |
+ |
|
334 |
+static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes, |
|
335 |
+ ILookInStream *inStream, UInt64 startPos, |
|
336 |
+ Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain, |
|
337 |
+ Byte *tempBuf[]) |
|
338 |
+{ |
|
339 |
+ UInt32 ci; |
|
340 |
+ SizeT tempSizes[3] = { 0, 0, 0}; |
|
341 |
+ SizeT tempSize3 = 0; |
|
342 |
+ Byte *tempBuf3 = 0; |
|
343 |
+ |
|
344 |
+ RINOK(CheckSupportedFolder(folder)); |
|
345 |
+ |
|
346 |
+ for (ci = 0; ci < folder->NumCoders; ci++) |
|
347 |
+ { |
|
348 |
+ CSzCoderInfo *coder = &folder->Coders[ci]; |
|
349 |
+ |
|
350 |
+ if (IS_MAIN_METHOD((UInt32)coder->MethodID)) |
|
351 |
+ { |
|
352 |
+ UInt32 si = 0; |
|
353 |
+ UInt64 offset; |
|
354 |
+ UInt64 inSize; |
|
355 |
+ Byte *outBufCur = outBuffer; |
|
356 |
+ SizeT outSizeCur = outSize; |
|
357 |
+ if (folder->NumCoders == 4) |
|
358 |
+ { |
|
359 |
+ UInt32 indices[] = { 3, 2, 0 }; |
|
360 |
+ UInt64 unpackSize = folder->UnpackSizes[ci]; |
|
361 |
+ si = indices[ci]; |
|
362 |
+ if (ci < 2) |
|
363 |
+ { |
|
364 |
+ Byte *temp; |
|
365 |
+ outSizeCur = (SizeT)unpackSize; |
|
366 |
+ if (outSizeCur != unpackSize) |
|
367 |
+ return SZ_ERROR_MEM; |
|
368 |
+ temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur); |
|
369 |
+ if (temp == 0 && outSizeCur != 0) |
|
370 |
+ return SZ_ERROR_MEM; |
|
371 |
+ outBufCur = tempBuf[1 - ci] = temp; |
|
372 |
+ tempSizes[1 - ci] = outSizeCur; |
|
373 |
+ } |
|
374 |
+ else if (ci == 2) |
|
375 |
+ { |
|
376 |
+ if (unpackSize > outSize) /* check it */ |
|
377 |
+ return SZ_ERROR_PARAM; |
|
378 |
+ tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize); |
|
379 |
+ tempSize3 = outSizeCur = (SizeT)unpackSize; |
|
380 |
+ } |
|
381 |
+ else |
|
382 |
+ return SZ_ERROR_UNSUPPORTED; |
|
383 |
+ } |
|
384 |
+ offset = GetSum(packSizes, si); |
|
385 |
+ inSize = packSizes[si]; |
|
386 |
+ RINOK(LookInStream_SeekTo(inStream, startPos + offset)); |
|
387 |
+ |
|
388 |
+ if (coder->MethodID == k_Copy) |
|
389 |
+ { |
|
390 |
+ if (inSize != outSizeCur) /* check it */ |
|
391 |
+ return SZ_ERROR_DATA; |
|
392 |
+ RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); |
|
393 |
+ } |
|
394 |
+ else if (coder->MethodID == k_LZMA) |
|
395 |
+ { |
|
396 |
+ RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); |
|
397 |
+ } |
|
398 |
+ else if (coder->MethodID == k_LZMA2) |
|
399 |
+ { |
|
400 |
+ RINOK(SzDecodeLzma2(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); |
|
401 |
+ } |
|
402 |
+ else |
|
403 |
+ { |
|
404 |
+ #ifdef _7ZIP_PPMD_SUPPPORT |
|
405 |
+ RINOK(SzDecodePpmd(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); |
|
406 |
+ #else |
|
407 |
+ return SZ_ERROR_UNSUPPORTED; |
|
408 |
+ #endif |
|
409 |
+ } |
|
410 |
+ } |
|
411 |
+ else if (coder->MethodID == k_BCJ2) |
|
412 |
+ { |
|
413 |
+ UInt64 offset = GetSum(packSizes, 1); |
|
414 |
+ UInt64 s3Size = packSizes[1]; |
|
415 |
+ SRes res; |
|
416 |
+ if (ci != 3) |
|
417 |
+ return SZ_ERROR_UNSUPPORTED; |
|
418 |
+ RINOK(LookInStream_SeekTo(inStream, startPos + offset)); |
|
419 |
+ tempSizes[2] = (SizeT)s3Size; |
|
420 |
+ if (tempSizes[2] != s3Size) |
|
421 |
+ return SZ_ERROR_MEM; |
|
422 |
+ tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]); |
|
423 |
+ if (tempBuf[2] == 0 && tempSizes[2] != 0) |
|
424 |
+ return SZ_ERROR_MEM; |
|
425 |
+ res = SzDecodeCopy(s3Size, inStream, tempBuf[2]); |
|
426 |
+ RINOK(res) |
|
427 |
+ |
|
428 |
+ res = Bcj2_Decode( |
|
429 |
+ tempBuf3, tempSize3, |
|
430 |
+ tempBuf[0], tempSizes[0], |
|
431 |
+ tempBuf[1], tempSizes[1], |
|
432 |
+ tempBuf[2], tempSizes[2], |
|
433 |
+ outBuffer, outSize); |
|
434 |
+ RINOK(res) |
|
435 |
+ } |
|
436 |
+ else |
|
437 |
+ { |
|
438 |
+ if (ci != 1) |
|
439 |
+ return SZ_ERROR_UNSUPPORTED; |
|
440 |
+ switch(coder->MethodID) |
|
441 |
+ { |
|
442 |
+ case k_BCJ: |
|
443 |
+ { |
|
444 |
+ UInt32 state; |
|
445 |
+ x86_Convert_Init(state); |
|
446 |
+ x86_Convert(outBuffer, outSize, 0, &state, 0); |
|
447 |
+ break; |
|
448 |
+ } |
|
449 |
+ CASE_BRA_CONV(ARM) |
|
450 |
+ default: |
|
451 |
+ return SZ_ERROR_UNSUPPORTED; |
|
452 |
+ } |
|
453 |
+ } |
|
454 |
+ } |
|
455 |
+ return SZ_OK; |
|
456 |
+} |
|
457 |
+ |
|
458 |
+SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes, |
|
459 |
+ ILookInStream *inStream, UInt64 startPos, |
|
460 |
+ Byte *outBuffer, size_t outSize, ISzAlloc *allocMain) |
|
461 |
+{ |
|
462 |
+ Byte *tempBuf[3] = { 0, 0, 0}; |
|
463 |
+ int i; |
|
464 |
+ SRes res = SzFolder_Decode2(folder, packSizes, inStream, startPos, |
|
465 |
+ outBuffer, (SizeT)outSize, allocMain, tempBuf); |
|
466 |
+ for (i = 0; i < 3; i++) |
|
467 |
+ IAlloc_Free(allocMain, tempBuf[i]); |
|
468 |
+ return res; |
|
469 |
+} |
... | ... |
@@ -1,263 +1,284 @@ |
1 |
-/* 7zFile.c -- File IO |
|
2 |
-2008-11-22 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#include "7zFile.h" |
|
5 |
- |
|
6 |
-#ifndef USE_WINDOWS_FILE |
|
7 |
- |
|
8 |
-#include <errno.h> |
|
9 |
- |
|
10 |
-#endif |
|
11 |
- |
|
12 |
-#ifdef USE_WINDOWS_FILE |
|
13 |
- |
|
14 |
-/* |
|
15 |
- ReadFile and WriteFile functions in Windows have BUG: |
|
16 |
- If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) |
|
17 |
- from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES |
|
18 |
- (Insufficient system resources exist to complete the requested service). |
|
19 |
- Probably in some version of Windows there are problems with other sizes: |
|
20 |
- for 32 MB (maybe also for 16 MB). |
|
21 |
- And message can be "Network connection was lost" |
|
22 |
-*/ |
|
23 |
- |
|
24 |
-#define kChunkSizeMax (1 << 22) |
|
25 |
- |
|
26 |
-#endif |
|
27 |
- |
|
28 |
-void File_Construct(CSzFile *p) |
|
29 |
-{ |
|
30 |
- #ifdef USE_WINDOWS_FILE |
|
31 |
- p->handle = INVALID_HANDLE_VALUE; |
|
32 |
- #else |
|
33 |
- p->file = NULL; |
|
34 |
- #endif |
|
35 |
-} |
|
36 |
- |
|
37 |
-static WRes File_Open(CSzFile *p, const char *name, int writeMode) |
|
38 |
-{ |
|
39 |
- #ifdef USE_WINDOWS_FILE |
|
40 |
- p->handle = CreateFileA(name, |
|
41 |
- writeMode ? GENERIC_WRITE : GENERIC_READ, |
|
42 |
- FILE_SHARE_READ, NULL, |
|
43 |
- writeMode ? CREATE_ALWAYS : OPEN_EXISTING, |
|
44 |
- FILE_ATTRIBUTE_NORMAL, NULL); |
|
45 |
- return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); |
|
46 |
- #else |
|
47 |
- p->file = fopen(name, writeMode ? "wb+" : "rb"); |
|
48 |
- return (p->file != 0) ? 0 : errno; |
|
49 |
- #endif |
|
50 |
-} |
|
51 |
- |
|
52 |
-WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); } |
|
53 |
-WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); } |
|
54 |
- |
|
55 |
-WRes File_Close(CSzFile *p) |
|
56 |
-{ |
|
57 |
- #ifdef USE_WINDOWS_FILE |
|
58 |
- if (p->handle != INVALID_HANDLE_VALUE) |
|
59 |
- { |
|
60 |
- if (!CloseHandle(p->handle)) |
|
61 |
- return GetLastError(); |
|
62 |
- p->handle = INVALID_HANDLE_VALUE; |
|
63 |
- } |
|
64 |
- #else |
|
65 |
- if (p->file != NULL) |
|
66 |
- { |
|
67 |
- int res = fclose(p->file); |
|
68 |
- if (res != 0) |
|
69 |
- return res; |
|
70 |
- p->file = NULL; |
|
71 |
- } |
|
72 |
- #endif |
|
73 |
- return 0; |
|
74 |
-} |
|
75 |
- |
|
76 |
-WRes File_Read(CSzFile *p, void *data, size_t *size) |
|
77 |
-{ |
|
78 |
- size_t originalSize = *size; |
|
79 |
- if (originalSize == 0) |
|
80 |
- return 0; |
|
81 |
- |
|
82 |
- #ifdef USE_WINDOWS_FILE |
|
83 |
- |
|
84 |
- *size = 0; |
|
85 |
- do |
|
86 |
- { |
|
87 |
- DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; |
|
88 |
- DWORD processed = 0; |
|
89 |
- BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL); |
|
90 |
- data = (void *)((Byte *)data + processed); |
|
91 |
- originalSize -= processed; |
|
92 |
- *size += processed; |
|
93 |
- if (!res) |
|
94 |
- return GetLastError(); |
|
95 |
- if (processed == 0) |
|
96 |
- break; |
|
97 |
- } |
|
98 |
- while (originalSize > 0); |
|
99 |
- return 0; |
|
100 |
- |
|
101 |
- #else |
|
102 |
- |
|
103 |
- *size = fread(data, 1, originalSize, p->file); |
|
104 |
- if (*size == originalSize) |
|
105 |
- return 0; |
|
106 |
- return ferror(p->file); |
|
107 |
- |
|
108 |
- #endif |
|
109 |
-} |
|
110 |
- |
|
111 |
-WRes File_Write(CSzFile *p, const void *data, size_t *size) |
|
112 |
-{ |
|
113 |
- size_t originalSize = *size; |
|
114 |
- if (originalSize == 0) |
|
115 |
- return 0; |
|
116 |
- |
|
117 |
- #ifdef USE_WINDOWS_FILE |
|
118 |
- |
|
119 |
- *size = 0; |
|
120 |
- do |
|
121 |
- { |
|
122 |
- DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; |
|
123 |
- DWORD processed = 0; |
|
124 |
- BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL); |
|
125 |
- data = (void *)((Byte *)data + processed); |
|
126 |
- originalSize -= processed; |
|
127 |
- *size += processed; |
|
128 |
- if (!res) |
|
129 |
- return GetLastError(); |
|
130 |
- if (processed == 0) |
|
131 |
- break; |
|
132 |
- } |
|
133 |
- while (originalSize > 0); |
|
134 |
- return 0; |
|
135 |
- |
|
136 |
- #else |
|
137 |
- |
|
138 |
- *size = fwrite(data, 1, originalSize, p->file); |
|
139 |
- if (*size == originalSize) |
|
140 |
- return 0; |
|
141 |
- return ferror(p->file); |
|
142 |
- |
|
143 |
- #endif |
|
144 |
-} |
|
145 |
- |
|
146 |
-WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin) |
|
147 |
-{ |
|
148 |
- #ifdef USE_WINDOWS_FILE |
|
149 |
- |
|
150 |
- LARGE_INTEGER value; |
|
151 |
- DWORD moveMethod; |
|
152 |
- value.LowPart = (DWORD)*pos; |
|
153 |
- value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */ |
|
154 |
- switch (origin) |
|
155 |
- { |
|
156 |
- case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break; |
|
157 |
- case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break; |
|
158 |
- case SZ_SEEK_END: moveMethod = FILE_END; break; |
|
159 |
- default: return ERROR_INVALID_PARAMETER; |
|
160 |
- } |
|
161 |
- value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod); |
|
162 |
- if (value.LowPart == 0xFFFFFFFF) |
|
163 |
- { |
|
164 |
- WRes res = GetLastError(); |
|
165 |
- if (res != NO_ERROR) |
|
166 |
- return res; |
|
167 |
- } |
|
168 |
- *pos = ((Int64)value.HighPart << 32) | value.LowPart; |
|
169 |
- return 0; |
|
170 |
- |
|
171 |
- #else |
|
172 |
- |
|
173 |
- int moveMethod; |
|
174 |
- int res; |
|
175 |
- switch (origin) |
|
176 |
- { |
|
177 |
- case SZ_SEEK_SET: moveMethod = SEEK_SET; break; |
|
178 |
- case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break; |
|
179 |
- case SZ_SEEK_END: moveMethod = SEEK_END; break; |
|
180 |
- default: return 1; |
|
181 |
- } |
|
182 |
- res = fseek(p->file, (long)*pos, moveMethod); |
|
183 |
- *pos = ftell(p->file); |
|
184 |
- return res; |
|
185 |
- |
|
186 |
- #endif |
|
187 |
-} |
|
188 |
- |
|
189 |
-WRes File_GetLength(CSzFile *p, UInt64 *length) |
|
190 |
-{ |
|
191 |
- #ifdef USE_WINDOWS_FILE |
|
192 |
- |
|
193 |
- DWORD sizeHigh; |
|
194 |
- DWORD sizeLow = GetFileSize(p->handle, &sizeHigh); |
|
195 |
- if (sizeLow == 0xFFFFFFFF) |
|
196 |
- { |
|
197 |
- DWORD res = GetLastError(); |
|
198 |
- if (res != NO_ERROR) |
|
199 |
- return res; |
|
200 |
- } |
|
201 |
- *length = (((UInt64)sizeHigh) << 32) + sizeLow; |
|
202 |
- return 0; |
|
203 |
- |
|
204 |
- #else |
|
205 |
- |
|
206 |
- long pos = ftell(p->file); |
|
207 |
- int res = fseek(p->file, 0, SEEK_END); |
|
208 |
- *length = ftell(p->file); |
|
209 |
- fseek(p->file, pos, SEEK_SET); |
|
210 |
- return res; |
|
211 |
- |
|
212 |
- #endif |
|
213 |
-} |
|
214 |
- |
|
215 |
- |
|
216 |
-/* ---------- FileSeqInStream ---------- */ |
|
217 |
- |
|
218 |
-static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size) |
|
219 |
-{ |
|
220 |
- CFileSeqInStream *p = (CFileSeqInStream *)pp; |
|
221 |
- return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ; |
|
222 |
-} |
|
223 |
- |
|
224 |
-void FileSeqInStream_CreateVTable(CFileSeqInStream *p) |
|
225 |
-{ |
|
226 |
- p->s.Read = FileSeqInStream_Read; |
|
227 |
-} |
|
228 |
- |
|
229 |
- |
|
230 |
-/* ---------- FileInStream ---------- */ |
|
231 |
- |
|
232 |
-static SRes FileInStream_Read(void *pp, void *buf, size_t *size) |
|
233 |
-{ |
|
234 |
- CFileInStream *p = (CFileInStream *)pp; |
|
235 |
- return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ; |
|
236 |
-} |
|
237 |
- |
|
238 |
-static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin) |
|
239 |
-{ |
|
240 |
- CFileInStream *p = (CFileInStream *)pp; |
|
241 |
- return File_Seek(&p->file, pos, origin); |
|
242 |
-} |
|
243 |
- |
|
244 |
-void FileInStream_CreateVTable(CFileInStream *p) |
|
245 |
-{ |
|
246 |
- p->s.Read = FileInStream_Read; |
|
247 |
- p->s.Seek = FileInStream_Seek; |
|
248 |
-} |
|
249 |
- |
|
250 |
- |
|
251 |
-/* ---------- FileOutStream ---------- */ |
|
252 |
- |
|
253 |
-static size_t FileOutStream_Write(void *pp, const void *data, size_t size) |
|
254 |
-{ |
|
255 |
- CFileOutStream *p = (CFileOutStream *)pp; |
|
256 |
- File_Write(&p->file, data, &size); |
|
257 |
- return size; |
|
258 |
-} |
|
259 |
- |
|
260 |
-void FileOutStream_CreateVTable(CFileOutStream *p) |
|
261 |
-{ |
|
262 |
- p->s.Write = FileOutStream_Write; |
|
263 |
-} |
|
1 |
+/* 7zFile.c -- File IO |
|
2 |
+2009-11-24 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#include "7zFile.h" |
|
5 |
+ |
|
6 |
+#ifndef USE_WINDOWS_FILE |
|
7 |
+ |
|
8 |
+#ifndef UNDER_CE |
|
9 |
+#include <errno.h> |
|
10 |
+#endif |
|
11 |
+ |
|
12 |
+#else |
|
13 |
+ |
|
14 |
+/* |
|
15 |
+ ReadFile and WriteFile functions in Windows have BUG: |
|
16 |
+ If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) |
|
17 |
+ from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES |
|
18 |
+ (Insufficient system resources exist to complete the requested service). |
|
19 |
+ Probably in some version of Windows there are problems with other sizes: |
|
20 |
+ for 32 MB (maybe also for 16 MB). |
|
21 |
+ And message can be "Network connection was lost" |
|
22 |
+*/ |
|
23 |
+ |
|
24 |
+#define kChunkSizeMax (1 << 22) |
|
25 |
+ |
|
26 |
+#endif |
|
27 |
+ |
|
28 |
+void File_Construct(CSzFile *p) |
|
29 |
+{ |
|
30 |
+ #ifdef USE_WINDOWS_FILE |
|
31 |
+ p->handle = INVALID_HANDLE_VALUE; |
|
32 |
+ #else |
|
33 |
+ p->file = NULL; |
|
34 |
+ #endif |
|
35 |
+} |
|
36 |
+ |
|
37 |
+#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE) |
|
38 |
+static WRes File_Open(CSzFile *p, const char *name, int writeMode) |
|
39 |
+{ |
|
40 |
+ #ifdef USE_WINDOWS_FILE |
|
41 |
+ p->handle = CreateFileA(name, |
|
42 |
+ writeMode ? GENERIC_WRITE : GENERIC_READ, |
|
43 |
+ FILE_SHARE_READ, NULL, |
|
44 |
+ writeMode ? CREATE_ALWAYS : OPEN_EXISTING, |
|
45 |
+ FILE_ATTRIBUTE_NORMAL, NULL); |
|
46 |
+ return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); |
|
47 |
+ #else |
|
48 |
+ p->file = fopen(name, writeMode ? "wb+" : "rb"); |
|
49 |
+ return (p->file != 0) ? 0 : |
|
50 |
+ #ifdef UNDER_CE |
|
51 |
+ 2; /* ENOENT */ |
|
52 |
+ #else |
|
53 |
+ errno; |
|
54 |
+ #endif |
|
55 |
+ #endif |
|
56 |
+} |
|
57 |
+ |
|
58 |
+WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); } |
|
59 |
+WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); } |
|
60 |
+#endif |
|
61 |
+ |
|
62 |
+#ifdef USE_WINDOWS_FILE |
|
63 |
+static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode) |
|
64 |
+{ |
|
65 |
+ p->handle = CreateFileW(name, |
|
66 |
+ writeMode ? GENERIC_WRITE : GENERIC_READ, |
|
67 |
+ FILE_SHARE_READ, NULL, |
|
68 |
+ writeMode ? CREATE_ALWAYS : OPEN_EXISTING, |
|
69 |
+ FILE_ATTRIBUTE_NORMAL, NULL); |
|
70 |
+ return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); |
|
71 |
+} |
|
72 |
+WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); } |
|
73 |
+WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); } |
|
74 |
+#endif |
|
75 |
+ |
|
76 |
+WRes File_Close(CSzFile *p) |
|
77 |
+{ |
|
78 |
+ #ifdef USE_WINDOWS_FILE |
|
79 |
+ if (p->handle != INVALID_HANDLE_VALUE) |
|
80 |
+ { |
|
81 |
+ if (!CloseHandle(p->handle)) |
|
82 |
+ return GetLastError(); |
|
83 |
+ p->handle = INVALID_HANDLE_VALUE; |
|
84 |
+ } |
|
85 |
+ #else |
|
86 |
+ if (p->file != NULL) |
|
87 |
+ { |
|
88 |
+ int res = fclose(p->file); |
|
89 |
+ if (res != 0) |
|
90 |
+ return res; |
|
91 |
+ p->file = NULL; |
|
92 |
+ } |
|
93 |
+ #endif |
|
94 |
+ return 0; |
|
95 |
+} |
|
96 |
+ |
|
97 |
+WRes File_Read(CSzFile *p, void *data, size_t *size) |
|
98 |
+{ |
|
99 |
+ size_t originalSize = *size; |
|
100 |
+ if (originalSize == 0) |
|
101 |
+ return 0; |
|
102 |
+ |
|
103 |
+ #ifdef USE_WINDOWS_FILE |
|
104 |
+ |
|
105 |
+ *size = 0; |
|
106 |
+ do |
|
107 |
+ { |
|
108 |
+ DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; |
|
109 |
+ DWORD processed = 0; |
|
110 |
+ BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL); |
|
111 |
+ data = (void *)((Byte *)data + processed); |
|
112 |
+ originalSize -= processed; |
|
113 |
+ *size += processed; |
|
114 |
+ if (!res) |
|
115 |
+ return GetLastError(); |
|
116 |
+ if (processed == 0) |
|
117 |
+ break; |
|
118 |
+ } |
|
119 |
+ while (originalSize > 0); |
|
120 |
+ return 0; |
|
121 |
+ |
|
122 |
+ #else |
|
123 |
+ |
|
124 |
+ *size = fread(data, 1, originalSize, p->file); |
|
125 |
+ if (*size == originalSize) |
|
126 |
+ return 0; |
|
127 |
+ return ferror(p->file); |
|
128 |
+ |
|
129 |
+ #endif |
|
130 |
+} |
|
131 |
+ |
|
132 |
+WRes File_Write(CSzFile *p, const void *data, size_t *size) |
|
133 |
+{ |
|
134 |
+ size_t originalSize = *size; |
|
135 |
+ if (originalSize == 0) |
|
136 |
+ return 0; |
|
137 |
+ |
|
138 |
+ #ifdef USE_WINDOWS_FILE |
|
139 |
+ |
|
140 |
+ *size = 0; |
|
141 |
+ do |
|
142 |
+ { |
|
143 |
+ DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; |
|
144 |
+ DWORD processed = 0; |
|
145 |
+ BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL); |
|
146 |
+ data = (void *)((Byte *)data + processed); |
|
147 |
+ originalSize -= processed; |
|
148 |
+ *size += processed; |
|
149 |
+ if (!res) |
|
150 |
+ return GetLastError(); |
|
151 |
+ if (processed == 0) |
|
152 |
+ break; |
|
153 |
+ } |
|
154 |
+ while (originalSize > 0); |
|
155 |
+ return 0; |
|
156 |
+ |
|
157 |
+ #else |
|
158 |
+ |
|
159 |
+ *size = fwrite(data, 1, originalSize, p->file); |
|
160 |
+ if (*size == originalSize) |
|
161 |
+ return 0; |
|
162 |
+ return ferror(p->file); |
|
163 |
+ |
|
164 |
+ #endif |
|
165 |
+} |
|
166 |
+ |
|
167 |
+WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin) |
|
168 |
+{ |
|
169 |
+ #ifdef USE_WINDOWS_FILE |
|
170 |
+ |
|
171 |
+ LARGE_INTEGER value; |
|
172 |
+ DWORD moveMethod; |
|
173 |
+ value.LowPart = (DWORD)*pos; |
|
174 |
+ value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */ |
|
175 |
+ switch (origin) |
|
176 |
+ { |
|
177 |
+ case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break; |
|
178 |
+ case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break; |
|
179 |
+ case SZ_SEEK_END: moveMethod = FILE_END; break; |
|
180 |
+ default: return ERROR_INVALID_PARAMETER; |
|
181 |
+ } |
|
182 |
+ value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod); |
|
183 |
+ if (value.LowPart == 0xFFFFFFFF) |
|
184 |
+ { |
|
185 |
+ WRes res = GetLastError(); |
|
186 |
+ if (res != NO_ERROR) |
|
187 |
+ return res; |
|
188 |
+ } |
|
189 |
+ *pos = ((Int64)value.HighPart << 32) | value.LowPart; |
|
190 |
+ return 0; |
|
191 |
+ |
|
192 |
+ #else |
|
193 |
+ |
|
194 |
+ int moveMethod; |
|
195 |
+ int res; |
|
196 |
+ switch (origin) |
|
197 |
+ { |
|
198 |
+ case SZ_SEEK_SET: moveMethod = SEEK_SET; break; |
|
199 |
+ case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break; |
|
200 |
+ case SZ_SEEK_END: moveMethod = SEEK_END; break; |
|
201 |
+ default: return 1; |
|
202 |
+ } |
|
203 |
+ res = fseek(p->file, (long)*pos, moveMethod); |
|
204 |
+ *pos = ftell(p->file); |
|
205 |
+ return res; |
|
206 |
+ |
|
207 |
+ #endif |
|
208 |
+} |
|
209 |
+ |
|
210 |
+WRes File_GetLength(CSzFile *p, UInt64 *length) |
|
211 |
+{ |
|
212 |
+ #ifdef USE_WINDOWS_FILE |
|
213 |
+ |
|
214 |
+ DWORD sizeHigh; |
|
215 |
+ DWORD sizeLow = GetFileSize(p->handle, &sizeHigh); |
|
216 |
+ if (sizeLow == 0xFFFFFFFF) |
|
217 |
+ { |
|
218 |
+ DWORD res = GetLastError(); |
|
219 |
+ if (res != NO_ERROR) |
|
220 |
+ return res; |
|
221 |
+ } |
|
222 |
+ *length = (((UInt64)sizeHigh) << 32) + sizeLow; |
|
223 |
+ return 0; |
|
224 |
+ |
|
225 |
+ #else |
|
226 |
+ |
|
227 |
+ long pos = ftell(p->file); |
|
228 |
+ int res = fseek(p->file, 0, SEEK_END); |
|
229 |
+ *length = ftell(p->file); |
|
230 |
+ fseek(p->file, pos, SEEK_SET); |
|
231 |
+ return res; |
|
232 |
+ |
|
233 |
+ #endif |
|
234 |
+} |
|
235 |
+ |
|
236 |
+ |
|
237 |
+/* ---------- FileSeqInStream ---------- */ |
|
238 |
+ |
|
239 |
+static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size) |
|
240 |
+{ |
|
241 |
+ CFileSeqInStream *p = (CFileSeqInStream *)pp; |
|
242 |
+ return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ; |
|
243 |
+} |
|
244 |
+ |
|
245 |
+void FileSeqInStream_CreateVTable(CFileSeqInStream *p) |
|
246 |
+{ |
|
247 |
+ p->s.Read = FileSeqInStream_Read; |
|
248 |
+} |
|
249 |
+ |
|
250 |
+ |
|
251 |
+/* ---------- FileInStream ---------- */ |
|
252 |
+ |
|
253 |
+static SRes FileInStream_Read(void *pp, void *buf, size_t *size) |
|
254 |
+{ |
|
255 |
+ CFileInStream *p = (CFileInStream *)pp; |
|
256 |
+ return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ; |
|
257 |
+} |
|
258 |
+ |
|
259 |
+static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin) |
|
260 |
+{ |
|
261 |
+ CFileInStream *p = (CFileInStream *)pp; |
|
262 |
+ return File_Seek(&p->file, pos, origin); |
|
263 |
+} |
|
264 |
+ |
|
265 |
+void FileInStream_CreateVTable(CFileInStream *p) |
|
266 |
+{ |
|
267 |
+ p->s.Read = FileInStream_Read; |
|
268 |
+ p->s.Seek = FileInStream_Seek; |
|
269 |
+} |
|
270 |
+ |
|
271 |
+ |
|
272 |
+/* ---------- FileOutStream ---------- */ |
|
273 |
+ |
|
274 |
+static size_t FileOutStream_Write(void *pp, const void *data, size_t size) |
|
275 |
+{ |
|
276 |
+ CFileOutStream *p = (CFileOutStream *)pp; |
|
277 |
+ File_Write(&p->file, data, &size); |
|
278 |
+ return size; |
|
279 |
+} |
|
280 |
+ |
|
281 |
+void FileOutStream_CreateVTable(CFileOutStream *p) |
|
282 |
+{ |
|
283 |
+ p->s.Write = FileOutStream_Write; |
|
284 |
+} |
... | ... |
@@ -1,76 +1,84 @@ |
1 |
-/* 7zFile.h -- File IO |
|
2 |
-2008-11-22 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#ifndef __7Z_FILE_H |
|
5 |
-#define __7Z_FILE_H |
|
6 |
- |
|
7 |
-/* aCaB -- do not use HANDLE on win32 |
|
8 |
-#ifdef _WIN32 |
|
9 |
-#define USE_WINDOWS_FILE |
|
10 |
-#endif |
|
11 |
-*/ |
|
12 |
- |
|
13 |
-#ifdef USE_WINDOWS_FILE |
|
14 |
-#include <windows.h> |
|
15 |
-#else |
|
16 |
-#include <stdio.h> |
|
17 |
-#endif |
|
18 |
- |
|
19 |
-#include "Types.h" |
|
20 |
- |
|
21 |
- |
|
22 |
-/* ---------- File ---------- */ |
|
23 |
- |
|
24 |
-typedef struct |
|
25 |
-{ |
|
26 |
- #ifdef USE_WINDOWS_FILE |
|
27 |
- HANDLE handle; |
|
28 |
- #else |
|
29 |
- FILE *file; |
|
30 |
- #endif |
|
31 |
-} CSzFile; |
|
32 |
- |
|
33 |
-void File_Construct(CSzFile *p); |
|
34 |
-WRes InFile_Open(CSzFile *p, const char *name); |
|
35 |
-WRes OutFile_Open(CSzFile *p, const char *name); |
|
36 |
-WRes File_Close(CSzFile *p); |
|
37 |
- |
|
38 |
-/* reads max(*size, remain file's size) bytes */ |
|
39 |
-WRes File_Read(CSzFile *p, void *data, size_t *size); |
|
40 |
- |
|
41 |
-/* writes *size bytes */ |
|
42 |
-WRes File_Write(CSzFile *p, const void *data, size_t *size); |
|
43 |
- |
|
44 |
-WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin); |
|
45 |
-WRes File_GetLength(CSzFile *p, UInt64 *length); |
|
46 |
- |
|
47 |
- |
|
48 |
-/* ---------- FileInStream ---------- */ |
|
49 |
- |
|
50 |
-typedef struct |
|
51 |
-{ |
|
52 |
- ISeqInStream s; |
|
53 |
- CSzFile file; |
|
54 |
-} CFileSeqInStream; |
|
55 |
- |
|
56 |
-void FileSeqInStream_CreateVTable(CFileSeqInStream *p); |
|
57 |
- |
|
58 |
- |
|
59 |
-typedef struct |
|
60 |
-{ |
|
61 |
- ISeekInStream s; |
|
62 |
- CSzFile file; |
|
63 |
-} CFileInStream; |
|
64 |
- |
|
65 |
-void FileInStream_CreateVTable(CFileInStream *p); |
|
66 |
- |
|
67 |
- |
|
68 |
-typedef struct |
|
69 |
-{ |
|
70 |
- ISeqOutStream s; |
|
71 |
- CSzFile file; |
|
72 |
-} CFileOutStream; |
|
73 |
- |
|
74 |
-void FileOutStream_CreateVTable(CFileOutStream *p); |
|
75 |
- |
|
76 |
-#endif |
|
1 |
+/* 7zFile.h -- File IO |
|
2 |
+2009-11-24 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#ifndef __7Z_FILE_H |
|
5 |
+#define __7Z_FILE_H |
|
6 |
+ |
|
7 |
+#ifdef _WIN32 |
|
8 |
+#define USE_WINDOWS_FILE |
|
9 |
+#endif |
|
10 |
+ |
|
11 |
+#ifdef USE_WINDOWS_FILE |
|
12 |
+#include <windows.h> |
|
13 |
+#else |
|
14 |
+#include <stdio.h> |
|
15 |
+#endif |
|
16 |
+ |
|
17 |
+#include "Types.h" |
|
18 |
+ |
|
19 |
+EXTERN_C_BEGIN |
|
20 |
+ |
|
21 |
+/* ---------- File ---------- */ |
|
22 |
+ |
|
23 |
+typedef struct |
|
24 |
+{ |
|
25 |
+#ifdef USE_WINDOWS_FILE |
|
26 |
+ HANDLE handle; |
|
27 |
+#else |
|
28 |
+ FILE *file; |
|
29 |
+#endif |
|
30 |
+ fmap_t *fmap; |
|
31 |
+} CSzFile; |
|
32 |
+ |
|
33 |
+void File_Construct(CSzFile *p); |
|
34 |
+#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE) |
|
35 |
+WRes InFile_Open(CSzFile *p, const char *name); |
|
36 |
+WRes OutFile_Open(CSzFile *p, const char *name); |
|
37 |
+#endif |
|
38 |
+#ifdef USE_WINDOWS_FILE |
|
39 |
+WRes InFile_OpenW(CSzFile *p, const WCHAR *name); |
|
40 |
+WRes OutFile_OpenW(CSzFile *p, const WCHAR *name); |
|
41 |
+#endif |
|
42 |
+WRes File_Close(CSzFile *p); |
|
43 |
+ |
|
44 |
+/* reads max(*size, remain file's size) bytes */ |
|
45 |
+WRes File_Read(CSzFile *p, void *data, size_t *size); |
|
46 |
+ |
|
47 |
+/* writes *size bytes */ |
|
48 |
+WRes File_Write(CSzFile *p, const void *data, size_t *size); |
|
49 |
+ |
|
50 |
+WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin); |
|
51 |
+WRes File_GetLength(CSzFile *p, UInt64 *length); |
|
52 |
+ |
|
53 |
+ |
|
54 |
+/* ---------- FileInStream ---------- */ |
|
55 |
+ |
|
56 |
+typedef struct |
|
57 |
+{ |
|
58 |
+ ISeqInStream s; |
|
59 |
+ CSzFile file; |
|
60 |
+} CFileSeqInStream; |
|
61 |
+ |
|
62 |
+void FileSeqInStream_CreateVTable(CFileSeqInStream *p); |
|
63 |
+ |
|
64 |
+ |
|
65 |
+typedef struct |
|
66 |
+{ |
|
67 |
+ ISeekInStream s; |
|
68 |
+ CSzFile file; |
|
69 |
+} CFileInStream; |
|
70 |
+ |
|
71 |
+void FileInStream_CreateVTable(CFileInStream *p); |
|
72 |
+ |
|
73 |
+ |
|
74 |
+typedef struct |
|
75 |
+{ |
|
76 |
+ ISeqOutStream s; |
|
77 |
+ CSzFile file; |
|
78 |
+} CFileOutStream; |
|
79 |
+ |
|
80 |
+void FileOutStream_CreateVTable(CFileOutStream *p); |
|
81 |
+ |
|
82 |
+EXTERN_C_END |
|
83 |
+ |
|
84 |
+#endif |
77 | 85 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,1402 @@ |
0 |
+/* 7zIn.c -- 7z Input functions |
|
1 |
+2010-10-29 : Igor Pavlov : Public domain */ |
|
2 |
+ |
|
3 |
+#include <string.h> |
|
4 |
+ |
|
5 |
+#include "7z.h" |
|
6 |
+#include "7zCrc.h" |
|
7 |
+#include "CpuArch.h" |
|
8 |
+ |
|
9 |
+Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; |
|
10 |
+ |
|
11 |
+#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; } |
|
12 |
+ |
|
13 |
+#define NUM_FOLDER_CODERS_MAX 32 |
|
14 |
+#define NUM_CODER_STREAMS_MAX 32 |
|
15 |
+ |
|
16 |
+void SzCoderInfo_Init(CSzCoderInfo *p) |
|
17 |
+{ |
|
18 |
+ Buf_Init(&p->Props); |
|
19 |
+} |
|
20 |
+ |
|
21 |
+void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc) |
|
22 |
+{ |
|
23 |
+ Buf_Free(&p->Props, alloc); |
|
24 |
+ SzCoderInfo_Init(p); |
|
25 |
+} |
|
26 |
+ |
|
27 |
+void SzFolder_Init(CSzFolder *p) |
|
28 |
+{ |
|
29 |
+ p->Coders = 0; |
|
30 |
+ p->BindPairs = 0; |
|
31 |
+ p->PackStreams = 0; |
|
32 |
+ p->UnpackSizes = 0; |
|
33 |
+ p->NumCoders = 0; |
|
34 |
+ p->NumBindPairs = 0; |
|
35 |
+ p->NumPackStreams = 0; |
|
36 |
+ p->UnpackCRCDefined = 0; |
|
37 |
+ p->UnpackCRC = 0; |
|
38 |
+ p->NumUnpackStreams = 0; |
|
39 |
+} |
|
40 |
+ |
|
41 |
+void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc) |
|
42 |
+{ |
|
43 |
+ UInt32 i; |
|
44 |
+ if (p->Coders) |
|
45 |
+ for (i = 0; i < p->NumCoders; i++) |
|
46 |
+ SzCoderInfo_Free(&p->Coders[i], alloc); |
|
47 |
+ IAlloc_Free(alloc, p->Coders); |
|
48 |
+ IAlloc_Free(alloc, p->BindPairs); |
|
49 |
+ IAlloc_Free(alloc, p->PackStreams); |
|
50 |
+ IAlloc_Free(alloc, p->UnpackSizes); |
|
51 |
+ SzFolder_Init(p); |
|
52 |
+} |
|
53 |
+ |
|
54 |
+UInt32 SzFolder_GetNumOutStreams(CSzFolder *p) |
|
55 |
+{ |
|
56 |
+ UInt32 result = 0; |
|
57 |
+ UInt32 i; |
|
58 |
+ for (i = 0; i < p->NumCoders; i++) |
|
59 |
+ result += p->Coders[i].NumOutStreams; |
|
60 |
+ return result; |
|
61 |
+} |
|
62 |
+ |
|
63 |
+int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex) |
|
64 |
+{ |
|
65 |
+ UInt32 i; |
|
66 |
+ for (i = 0; i < p->NumBindPairs; i++) |
|
67 |
+ if (p->BindPairs[i].InIndex == inStreamIndex) |
|
68 |
+ return i; |
|
69 |
+ return -1; |
|
70 |
+} |
|
71 |
+ |
|
72 |
+ |
|
73 |
+int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex) |
|
74 |
+{ |
|
75 |
+ UInt32 i; |
|
76 |
+ for (i = 0; i < p->NumBindPairs; i++) |
|
77 |
+ if (p->BindPairs[i].OutIndex == outStreamIndex) |
|
78 |
+ return i; |
|
79 |
+ return -1; |
|
80 |
+} |
|
81 |
+ |
|
82 |
+UInt64 SzFolder_GetUnpackSize(CSzFolder *p) |
|
83 |
+{ |
|
84 |
+ int i = (int)SzFolder_GetNumOutStreams(p); |
|
85 |
+ if (i == 0) |
|
86 |
+ return 0; |
|
87 |
+ for (i--; i >= 0; i--) |
|
88 |
+ if (SzFolder_FindBindPairForOutStream(p, i) < 0) |
|
89 |
+ return p->UnpackSizes[i]; |
|
90 |
+ /* throw 1; */ |
|
91 |
+ return 0; |
|
92 |
+} |
|
93 |
+ |
|
94 |
+void SzFile_Init(CSzFileItem *p) |
|
95 |
+{ |
|
96 |
+ p->HasStream = 1; |
|
97 |
+ p->IsDir = 0; |
|
98 |
+ p->IsAnti = 0; |
|
99 |
+ p->CrcDefined = 0; |
|
100 |
+ p->MTimeDefined = 0; |
|
101 |
+} |
|
102 |
+ |
|
103 |
+void SzAr_Init(CSzAr *p) |
|
104 |
+{ |
|
105 |
+ p->PackSizes = 0; |
|
106 |
+ p->PackCRCsDefined = 0; |
|
107 |
+ p->PackCRCs = 0; |
|
108 |
+ p->Folders = 0; |
|
109 |
+ p->Files = 0; |
|
110 |
+ p->NumPackStreams = 0; |
|
111 |
+ p->NumFolders = 0; |
|
112 |
+ p->NumFiles = 0; |
|
113 |
+} |
|
114 |
+ |
|
115 |
+void SzAr_Free(CSzAr *p, ISzAlloc *alloc) |
|
116 |
+{ |
|
117 |
+ UInt32 i; |
|
118 |
+ if (p->Folders) |
|
119 |
+ for (i = 0; i < p->NumFolders; i++) |
|
120 |
+ SzFolder_Free(&p->Folders[i], alloc); |
|
121 |
+ |
|
122 |
+ IAlloc_Free(alloc, p->PackSizes); |
|
123 |
+ IAlloc_Free(alloc, p->PackCRCsDefined); |
|
124 |
+ IAlloc_Free(alloc, p->PackCRCs); |
|
125 |
+ IAlloc_Free(alloc, p->Folders); |
|
126 |
+ IAlloc_Free(alloc, p->Files); |
|
127 |
+ SzAr_Init(p); |
|
128 |
+} |
|
129 |
+ |
|
130 |
+ |
|
131 |
+void SzArEx_Init(CSzArEx *p) |
|
132 |
+{ |
|
133 |
+ SzAr_Init(&p->db); |
|
134 |
+ p->FolderStartPackStreamIndex = 0; |
|
135 |
+ p->PackStreamStartPositions = 0; |
|
136 |
+ p->FolderStartFileIndex = 0; |
|
137 |
+ p->FileIndexToFolderIndexMap = 0; |
|
138 |
+ p->FileNameOffsets = 0; |
|
139 |
+ Buf_Init(&p->FileNames); |
|
140 |
+} |
|
141 |
+ |
|
142 |
+void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc) |
|
143 |
+{ |
|
144 |
+ IAlloc_Free(alloc, p->FolderStartPackStreamIndex); |
|
145 |
+ IAlloc_Free(alloc, p->PackStreamStartPositions); |
|
146 |
+ IAlloc_Free(alloc, p->FolderStartFileIndex); |
|
147 |
+ IAlloc_Free(alloc, p->FileIndexToFolderIndexMap); |
|
148 |
+ |
|
149 |
+ IAlloc_Free(alloc, p->FileNameOffsets); |
|
150 |
+ Buf_Free(&p->FileNames, alloc); |
|
151 |
+ |
|
152 |
+ SzAr_Free(&p->db, alloc); |
|
153 |
+ SzArEx_Init(p); |
|
154 |
+} |
|
155 |
+ |
|
156 |
+/* |
|
157 |
+UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const |
|
158 |
+{ |
|
159 |
+ return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex]; |
|
160 |
+} |
|
161 |
+ |
|
162 |
+UInt64 GetFilePackSize(int fileIndex) const |
|
163 |
+{ |
|
164 |
+ int folderIndex = FileIndexToFolderIndexMap[fileIndex]; |
|
165 |
+ if (folderIndex >= 0) |
|
166 |
+ { |
|
167 |
+ const CSzFolder &folderInfo = Folders[folderIndex]; |
|
168 |
+ if (FolderStartFileIndex[folderIndex] == fileIndex) |
|
169 |
+ return GetFolderFullPackSize(folderIndex); |
|
170 |
+ } |
|
171 |
+ return 0; |
|
172 |
+} |
|
173 |
+*/ |
|
174 |
+ |
|
175 |
+#define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \ |
|
176 |
+ if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; } |
|
177 |
+ |
|
178 |
+static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc) |
|
179 |
+{ |
|
180 |
+ UInt32 startPos = 0; |
|
181 |
+ UInt64 startPosSize = 0; |
|
182 |
+ UInt32 i; |
|
183 |
+ UInt32 folderIndex = 0; |
|
184 |
+ UInt32 indexInFolder = 0; |
|
185 |
+ MY_ALLOC(UInt32, p->FolderStartPackStreamIndex, p->db.NumFolders, alloc); |
|
186 |
+ for (i = 0; i < p->db.NumFolders; i++) |
|
187 |
+ { |
|
188 |
+ p->FolderStartPackStreamIndex[i] = startPos; |
|
189 |
+ startPos += p->db.Folders[i].NumPackStreams; |
|
190 |
+ } |
|
191 |
+ |
|
192 |
+ MY_ALLOC(UInt64, p->PackStreamStartPositions, p->db.NumPackStreams, alloc); |
|
193 |
+ |
|
194 |
+ for (i = 0; i < p->db.NumPackStreams; i++) |
|
195 |
+ { |
|
196 |
+ p->PackStreamStartPositions[i] = startPosSize; |
|
197 |
+ startPosSize += p->db.PackSizes[i]; |
|
198 |
+ } |
|
199 |
+ |
|
200 |
+ MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders, alloc); |
|
201 |
+ MY_ALLOC(UInt32, p->FileIndexToFolderIndexMap, p->db.NumFiles, alloc); |
|
202 |
+ |
|
203 |
+ for (i = 0; i < p->db.NumFiles; i++) |
|
204 |
+ { |
|
205 |
+ CSzFileItem *file = p->db.Files + i; |
|
206 |
+ int emptyStream = !file->HasStream; |
|
207 |
+ if (emptyStream && indexInFolder == 0) |
|
208 |
+ { |
|
209 |
+ p->FileIndexToFolderIndexMap[i] = (UInt32)-1; |
|
210 |
+ continue; |
|
211 |
+ } |
|
212 |
+ if (indexInFolder == 0) |
|
213 |
+ { |
|
214 |
+ /* |
|
215 |
+ v3.13 incorrectly worked with empty folders |
|
216 |
+ v4.07: Loop for skipping empty folders |
|
217 |
+ */ |
|
218 |
+ for (;;) |
|
219 |
+ { |
|
220 |
+ if (folderIndex >= p->db.NumFolders) |
|
221 |
+ return SZ_ERROR_ARCHIVE; |
|
222 |
+ p->FolderStartFileIndex[folderIndex] = i; |
|
223 |
+ if (p->db.Folders[folderIndex].NumUnpackStreams != 0) |
|
224 |
+ break; |
|
225 |
+ folderIndex++; |
|
226 |
+ } |
|
227 |
+ } |
|
228 |
+ p->FileIndexToFolderIndexMap[i] = folderIndex; |
|
229 |
+ if (emptyStream) |
|
230 |
+ continue; |
|
231 |
+ indexInFolder++; |
|
232 |
+ if (indexInFolder >= p->db.Folders[folderIndex].NumUnpackStreams) |
|
233 |
+ { |
|
234 |
+ folderIndex++; |
|
235 |
+ indexInFolder = 0; |
|
236 |
+ } |
|
237 |
+ } |
|
238 |
+ return SZ_OK; |
|
239 |
+} |
|
240 |
+ |
|
241 |
+ |
|
242 |
+UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder) |
|
243 |
+{ |
|
244 |
+ return p->dataPos + |
|
245 |
+ p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder]; |
|
246 |
+} |
|
247 |
+ |
|
248 |
+int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize) |
|
249 |
+{ |
|
250 |
+ UInt32 packStreamIndex = p->FolderStartPackStreamIndex[folderIndex]; |
|
251 |
+ CSzFolder *folder = p->db.Folders + folderIndex; |
|
252 |
+ UInt64 size = 0; |
|
253 |
+ UInt32 i; |
|
254 |
+ for (i = 0; i < folder->NumPackStreams; i++) |
|
255 |
+ { |
|
256 |
+ UInt64 t = size + p->db.PackSizes[packStreamIndex + i]; |
|
257 |
+ if (t < size) /* check it */ |
|
258 |
+ return SZ_ERROR_FAIL; |
|
259 |
+ size = t; |
|
260 |
+ } |
|
261 |
+ *resSize = size; |
|
262 |
+ return SZ_OK; |
|
263 |
+} |
|
264 |
+ |
|
265 |
+ |
|
266 |
+/* |
|
267 |
+SRes SzReadTime(const CObjectVector<CBuf> &dataVector, |
|
268 |
+ CObjectVector<CSzFileItem> &files, UInt64 type) |
|
269 |
+{ |
|
270 |
+ CBoolVector boolVector; |
|
271 |
+ RINOK(ReadBoolVector2(files.Size(), boolVector)) |
|
272 |
+ |
|
273 |
+ CStreamSwitch streamSwitch; |
|
274 |
+ RINOK(streamSwitch.Set(this, &dataVector)); |
|
275 |
+ |
|
276 |
+ for (int i = 0; i < files.Size(); i++) |
|
277 |
+ { |
|
278 |
+ CSzFileItem &file = files[i]; |
|
279 |
+ CArchiveFileTime fileTime; |
|
280 |
+ bool defined = boolVector[i]; |
|
281 |
+ if (defined) |
|
282 |
+ { |
|
283 |
+ UInt32 low, high; |
|
284 |
+ RINOK(SzReadUInt32(low)); |
|
285 |
+ RINOK(SzReadUInt32(high)); |
|
286 |
+ fileTime.dwLowDateTime = low; |
|
287 |
+ fileTime.dwHighDateTime = high; |
|
288 |
+ } |
|
289 |
+ switch(type) |
|
290 |
+ { |
|
291 |
+ case k7zIdCTime: file.IsCTimeDefined = defined; if (defined) file.CTime = fileTime; break; |
|
292 |
+ case k7zIdATime: file.IsATimeDefined = defined; if (defined) file.ATime = fileTime; break; |
|
293 |
+ case k7zIdMTime: file.IsMTimeDefined = defined; if (defined) file.MTime = fileTime; break; |
|
294 |
+ } |
|
295 |
+ } |
|
296 |
+ return SZ_OK; |
|
297 |
+} |
|
298 |
+*/ |
|
299 |
+ |
|
300 |
+static int TestSignatureCandidate(Byte *testBytes) |
|
301 |
+{ |
|
302 |
+ size_t i; |
|
303 |
+ for (i = 0; i < k7zSignatureSize; i++) |
|
304 |
+ if (testBytes[i] != k7zSignature[i]) |
|
305 |
+ return 0; |
|
306 |
+ return 1; |
|
307 |
+} |
|
308 |
+ |
|
309 |
+typedef struct _CSzState |
|
310 |
+{ |
|
311 |
+ Byte *Data; |
|
312 |
+ size_t Size; |
|
313 |
+}CSzData; |
|
314 |
+ |
|
315 |
+static SRes SzReadByte(CSzData *sd, Byte *b) |
|
316 |
+{ |
|
317 |
+ if (sd->Size == 0) |
|
318 |
+ return SZ_ERROR_ARCHIVE; |
|
319 |
+ sd->Size--; |
|
320 |
+ *b = *sd->Data++; |
|
321 |
+ return SZ_OK; |
|
322 |
+} |
|
323 |
+ |
|
324 |
+static SRes SzReadBytes(CSzData *sd, Byte *data, size_t size) |
|
325 |
+{ |
|
326 |
+ size_t i; |
|
327 |
+ for (i = 0; i < size; i++) |
|
328 |
+ { |
|
329 |
+ RINOK(SzReadByte(sd, data + i)); |
|
330 |
+ } |
|
331 |
+ return SZ_OK; |
|
332 |
+} |
|
333 |
+ |
|
334 |
+static SRes SzReadUInt32(CSzData *sd, UInt32 *value) |
|
335 |
+{ |
|
336 |
+ int i; |
|
337 |
+ *value = 0; |
|
338 |
+ for (i = 0; i < 4; i++) |
|
339 |
+ { |
|
340 |
+ Byte b; |
|
341 |
+ RINOK(SzReadByte(sd, &b)); |
|
342 |
+ *value |= ((UInt32)(b) << (8 * i)); |
|
343 |
+ } |
|
344 |
+ return SZ_OK; |
|
345 |
+} |
|
346 |
+ |
|
347 |
+static SRes SzReadNumber(CSzData *sd, UInt64 *value) |
|
348 |
+{ |
|
349 |
+ Byte firstByte; |
|
350 |
+ Byte mask = 0x80; |
|
351 |
+ int i; |
|
352 |
+ RINOK(SzReadByte(sd, &firstByte)); |
|
353 |
+ *value = 0; |
|
354 |
+ for (i = 0; i < 8; i++) |
|
355 |
+ { |
|
356 |
+ Byte b; |
|
357 |
+ if ((firstByte & mask) == 0) |
|
358 |
+ { |
|
359 |
+ UInt64 highPart = firstByte & (mask - 1); |
|
360 |
+ *value += (highPart << (8 * i)); |
|
361 |
+ return SZ_OK; |
|
362 |
+ } |
|
363 |
+ RINOK(SzReadByte(sd, &b)); |
|
364 |
+ *value |= ((UInt64)b << (8 * i)); |
|
365 |
+ mask >>= 1; |
|
366 |
+ } |
|
367 |
+ return SZ_OK; |
|
368 |
+} |
|
369 |
+ |
|
370 |
+static SRes SzReadNumber32(CSzData *sd, UInt32 *value) |
|
371 |
+{ |
|
372 |
+ UInt64 value64; |
|
373 |
+ RINOK(SzReadNumber(sd, &value64)); |
|
374 |
+ if (value64 >= 0x80000000) |
|
375 |
+ return SZ_ERROR_UNSUPPORTED; |
|
376 |
+ if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2))) |
|
377 |
+ return SZ_ERROR_UNSUPPORTED; |
|
378 |
+ *value = (UInt32)value64; |
|
379 |
+ return SZ_OK; |
|
380 |
+} |
|
381 |
+ |
|
382 |
+static SRes SzReadID(CSzData *sd, UInt64 *value) |
|
383 |
+{ |
|
384 |
+ return SzReadNumber(sd, value); |
|
385 |
+} |
|
386 |
+ |
|
387 |
+static SRes SzSkeepDataSize(CSzData *sd, UInt64 size) |
|
388 |
+{ |
|
389 |
+ if (size > sd->Size) |
|
390 |
+ return SZ_ERROR_ARCHIVE; |
|
391 |
+ sd->Size -= (size_t)size; |
|
392 |
+ sd->Data += (size_t)size; |
|
393 |
+ return SZ_OK; |
|
394 |
+} |
|
395 |
+ |
|
396 |
+static SRes SzSkeepData(CSzData *sd) |
|
397 |
+{ |
|
398 |
+ UInt64 size; |
|
399 |
+ RINOK(SzReadNumber(sd, &size)); |
|
400 |
+ return SzSkeepDataSize(sd, size); |
|
401 |
+} |
|
402 |
+ |
|
403 |
+static SRes SzReadArchiveProperties(CSzData *sd) |
|
404 |
+{ |
|
405 |
+ for (;;) |
|
406 |
+ { |
|
407 |
+ UInt64 type; |
|
408 |
+ RINOK(SzReadID(sd, &type)); |
|
409 |
+ if (type == k7zIdEnd) |
|
410 |
+ break; |
|
411 |
+ SzSkeepData(sd); |
|
412 |
+ } |
|
413 |
+ return SZ_OK; |
|
414 |
+} |
|
415 |
+ |
|
416 |
+static SRes SzWaitAttribute(CSzData *sd, UInt64 attribute) |
|
417 |
+{ |
|
418 |
+ for (;;) |
|
419 |
+ { |
|
420 |
+ UInt64 type; |
|
421 |
+ RINOK(SzReadID(sd, &type)); |
|
422 |
+ if (type == attribute) |
|
423 |
+ return SZ_OK; |
|
424 |
+ if (type == k7zIdEnd) |
|
425 |
+ return SZ_ERROR_ARCHIVE; |
|
426 |
+ RINOK(SzSkeepData(sd)); |
|
427 |
+ } |
|
428 |
+} |
|
429 |
+ |
|
430 |
+static SRes SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc) |
|
431 |
+{ |
|
432 |
+ Byte b = 0; |
|
433 |
+ Byte mask = 0; |
|
434 |
+ size_t i; |
|
435 |
+ MY_ALLOC(Byte, *v, numItems, alloc); |
|
436 |
+ for (i = 0; i < numItems; i++) |
|
437 |
+ { |
|
438 |
+ if (mask == 0) |
|
439 |
+ { |
|
440 |
+ RINOK(SzReadByte(sd, &b)); |
|
441 |
+ mask = 0x80; |
|
442 |
+ } |
|
443 |
+ (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0); |
|
444 |
+ mask >>= 1; |
|
445 |
+ } |
|
446 |
+ return SZ_OK; |
|
447 |
+} |
|
448 |
+ |
|
449 |
+static SRes SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc) |
|
450 |
+{ |
|
451 |
+ Byte allAreDefined; |
|
452 |
+ size_t i; |
|
453 |
+ RINOK(SzReadByte(sd, &allAreDefined)); |
|
454 |
+ if (allAreDefined == 0) |
|
455 |
+ return SzReadBoolVector(sd, numItems, v, alloc); |
|
456 |
+ MY_ALLOC(Byte, *v, numItems, alloc); |
|
457 |
+ for (i = 0; i < numItems; i++) |
|
458 |
+ (*v)[i] = 1; |
|
459 |
+ return SZ_OK; |
|
460 |
+} |
|
461 |
+ |
|
462 |
+static SRes SzReadHashDigests( |
|
463 |
+ CSzData *sd, |
|
464 |
+ size_t numItems, |
|
465 |
+ Byte **digestsDefined, |
|
466 |
+ UInt32 **digests, |
|
467 |
+ ISzAlloc *alloc) |
|
468 |
+{ |
|
469 |
+ size_t i; |
|
470 |
+ RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, alloc)); |
|
471 |
+ MY_ALLOC(UInt32, *digests, numItems, alloc); |
|
472 |
+ for (i = 0; i < numItems; i++) |
|
473 |
+ if ((*digestsDefined)[i]) |
|
474 |
+ { |
|
475 |
+ RINOK(SzReadUInt32(sd, (*digests) + i)); |
|
476 |
+ } |
|
477 |
+ return SZ_OK; |
|
478 |
+} |
|
479 |
+ |
|
480 |
+static SRes SzReadPackInfo( |
|
481 |
+ CSzData *sd, |
|
482 |
+ UInt64 *dataOffset, |
|
483 |
+ UInt32 *numPackStreams, |
|
484 |
+ UInt64 **packSizes, |
|
485 |
+ Byte **packCRCsDefined, |
|
486 |
+ UInt32 **packCRCs, |
|
487 |
+ ISzAlloc *alloc) |
|
488 |
+{ |
|
489 |
+ UInt32 i; |
|
490 |
+ RINOK(SzReadNumber(sd, dataOffset)); |
|
491 |
+ RINOK(SzReadNumber32(sd, numPackStreams)); |
|
492 |
+ |
|
493 |
+ RINOK(SzWaitAttribute(sd, k7zIdSize)); |
|
494 |
+ |
|
495 |
+ MY_ALLOC(UInt64, *packSizes, (size_t)*numPackStreams, alloc); |
|
496 |
+ |
|
497 |
+ for (i = 0; i < *numPackStreams; i++) |
|
498 |
+ { |
|
499 |
+ RINOK(SzReadNumber(sd, (*packSizes) + i)); |
|
500 |
+ } |
|
501 |
+ |
|
502 |
+ for (;;) |
|
503 |
+ { |
|
504 |
+ UInt64 type; |
|
505 |
+ RINOK(SzReadID(sd, &type)); |
|
506 |
+ if (type == k7zIdEnd) |
|
507 |
+ break; |
|
508 |
+ if (type == k7zIdCRC) |
|
509 |
+ { |
|
510 |
+ RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc)); |
|
511 |
+ continue; |
|
512 |
+ } |
|
513 |
+ RINOK(SzSkeepData(sd)); |
|
514 |
+ } |
|
515 |
+ if (*packCRCsDefined == 0) |
|
516 |
+ { |
|
517 |
+ MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, alloc); |
|
518 |
+ MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, alloc); |
|
519 |
+ for (i = 0; i < *numPackStreams; i++) |
|
520 |
+ { |
|
521 |
+ (*packCRCsDefined)[i] = 0; |
|
522 |
+ (*packCRCs)[i] = 0; |
|
523 |
+ } |
|
524 |
+ } |
|
525 |
+ return SZ_OK; |
|
526 |
+} |
|
527 |
+ |
|
528 |
+static SRes SzReadSwitch(CSzData *sd) |
|
529 |
+{ |
|
530 |
+ Byte external; |
|
531 |
+ RINOK(SzReadByte(sd, &external)); |
|
532 |
+ return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED; |
|
533 |
+} |
|
534 |
+ |
|
535 |
+static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc) |
|
536 |
+{ |
|
537 |
+ UInt32 numCoders, numBindPairs, numPackStreams, i; |
|
538 |
+ UInt32 numInStreams = 0, numOutStreams = 0; |
|
539 |
+ |
|
540 |
+ RINOK(SzReadNumber32(sd, &numCoders)); |
|
541 |
+ if (numCoders > NUM_FOLDER_CODERS_MAX) |
|
542 |
+ return SZ_ERROR_UNSUPPORTED; |
|
543 |
+ folder->NumCoders = numCoders; |
|
544 |
+ |
|
545 |
+ MY_ALLOC(CSzCoderInfo, folder->Coders, (size_t)numCoders, alloc); |
|
546 |
+ |
|
547 |
+ for (i = 0; i < numCoders; i++) |
|
548 |
+ SzCoderInfo_Init(folder->Coders + i); |
|
549 |
+ |
|
550 |
+ for (i = 0; i < numCoders; i++) |
|
551 |
+ { |
|
552 |
+ Byte mainByte; |
|
553 |
+ CSzCoderInfo *coder = folder->Coders + i; |
|
554 |
+ { |
|
555 |
+ unsigned idSize, j; |
|
556 |
+ Byte longID[15]; |
|
557 |
+ RINOK(SzReadByte(sd, &mainByte)); |
|
558 |
+ idSize = (unsigned)(mainByte & 0xF); |
|
559 |
+ RINOK(SzReadBytes(sd, longID, idSize)); |
|
560 |
+ if (idSize > sizeof(coder->MethodID)) |
|
561 |
+ return SZ_ERROR_UNSUPPORTED; |
|
562 |
+ coder->MethodID = 0; |
|
563 |
+ for (j = 0; j < idSize; j++) |
|
564 |
+ coder->MethodID |= (UInt64)longID[idSize - 1 - j] << (8 * j); |
|
565 |
+ |
|
566 |
+ if ((mainByte & 0x10) != 0) |
|
567 |
+ { |
|
568 |
+ RINOK(SzReadNumber32(sd, &coder->NumInStreams)); |
|
569 |
+ RINOK(SzReadNumber32(sd, &coder->NumOutStreams)); |
|
570 |
+ if (coder->NumInStreams > NUM_CODER_STREAMS_MAX || |
|
571 |
+ coder->NumOutStreams > NUM_CODER_STREAMS_MAX) |
|
572 |
+ return SZ_ERROR_UNSUPPORTED; |
|
573 |
+ } |
|
574 |
+ else |
|
575 |
+ { |
|
576 |
+ coder->NumInStreams = 1; |
|
577 |
+ coder->NumOutStreams = 1; |
|
578 |
+ } |
|
579 |
+ if ((mainByte & 0x20) != 0) |
|
580 |
+ { |
|
581 |
+ UInt64 propertiesSize = 0; |
|
582 |
+ RINOK(SzReadNumber(sd, &propertiesSize)); |
|
583 |
+ if (!Buf_Create(&coder->Props, (size_t)propertiesSize, alloc)) |
|
584 |
+ return SZ_ERROR_MEM; |
|
585 |
+ RINOK(SzReadBytes(sd, coder->Props.data, (size_t)propertiesSize)); |
|
586 |
+ } |
|
587 |
+ } |
|
588 |
+ while ((mainByte & 0x80) != 0) |
|
589 |
+ { |
|
590 |
+ RINOK(SzReadByte(sd, &mainByte)); |
|
591 |
+ RINOK(SzSkeepDataSize(sd, (mainByte & 0xF))); |
|
592 |
+ if ((mainByte & 0x10) != 0) |
|
593 |
+ { |
|
594 |
+ UInt32 n; |
|
595 |
+ RINOK(SzReadNumber32(sd, &n)); |
|
596 |
+ RINOK(SzReadNumber32(sd, &n)); |
|
597 |
+ } |
|
598 |
+ if ((mainByte & 0x20) != 0) |
|
599 |
+ { |
|
600 |
+ UInt64 propertiesSize = 0; |
|
601 |
+ RINOK(SzReadNumber(sd, &propertiesSize)); |
|
602 |
+ RINOK(SzSkeepDataSize(sd, propertiesSize)); |
|
603 |
+ } |
|
604 |
+ } |
|
605 |
+ numInStreams += coder->NumInStreams; |
|
606 |
+ numOutStreams += coder->NumOutStreams; |
|
607 |
+ } |
|
608 |
+ |
|
609 |
+ if (numOutStreams == 0) |
|
610 |
+ return SZ_ERROR_UNSUPPORTED; |
|
611 |
+ |
|
612 |
+ folder->NumBindPairs = numBindPairs = numOutStreams - 1; |
|
613 |
+ MY_ALLOC(CSzBindPair, folder->BindPairs, (size_t)numBindPairs, alloc); |
|
614 |
+ |
|
615 |
+ for (i = 0; i < numBindPairs; i++) |
|
616 |
+ { |
|
617 |
+ CSzBindPair *bp = folder->BindPairs + i; |
|
618 |
+ RINOK(SzReadNumber32(sd, &bp->InIndex)); |
|
619 |
+ RINOK(SzReadNumber32(sd, &bp->OutIndex)); |
|
620 |
+ } |
|
621 |
+ |
|
622 |
+ if (numInStreams < numBindPairs) |
|
623 |
+ return SZ_ERROR_UNSUPPORTED; |
|
624 |
+ |
|
625 |
+ folder->NumPackStreams = numPackStreams = numInStreams - numBindPairs; |
|
626 |
+ MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackStreams, alloc); |
|
627 |
+ |
|
628 |
+ if (numPackStreams == 1) |
|
629 |
+ { |
|
630 |
+ for (i = 0; i < numInStreams ; i++) |
|
631 |
+ if (SzFolder_FindBindPairForInStream(folder, i) < 0) |
|
632 |
+ break; |
|
633 |
+ if (i == numInStreams) |
|
634 |
+ return SZ_ERROR_UNSUPPORTED; |
|
635 |
+ folder->PackStreams[0] = i; |
|
636 |
+ } |
|
637 |
+ else |
|
638 |
+ for (i = 0; i < numPackStreams; i++) |
|
639 |
+ { |
|
640 |
+ RINOK(SzReadNumber32(sd, folder->PackStreams + i)); |
|
641 |
+ } |
|
642 |
+ return SZ_OK; |
|
643 |
+} |
|
644 |
+ |
|
645 |
+static SRes SzReadUnpackInfo( |
|
646 |
+ CSzData *sd, |
|
647 |
+ UInt32 *numFolders, |
|
648 |
+ CSzFolder **folders, /* for alloc */ |
|
649 |
+ ISzAlloc *alloc, |
|
650 |
+ ISzAlloc *allocTemp) |
|
651 |
+{ |
|
652 |
+ UInt32 i; |
|
653 |
+ RINOK(SzWaitAttribute(sd, k7zIdFolder)); |
|
654 |
+ RINOK(SzReadNumber32(sd, numFolders)); |
|
655 |
+ { |
|
656 |
+ RINOK(SzReadSwitch(sd)); |
|
657 |
+ |
|
658 |
+ MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc); |
|
659 |
+ |
|
660 |
+ for (i = 0; i < *numFolders; i++) |
|
661 |
+ SzFolder_Init((*folders) + i); |
|
662 |
+ |
|
663 |
+ for (i = 0; i < *numFolders; i++) |
|
664 |
+ { |
|
665 |
+ RINOK(SzGetNextFolderItem(sd, (*folders) + i, alloc)); |
|
666 |
+ } |
|
667 |
+ } |
|
668 |
+ |
|
669 |
+ RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize)); |
|
670 |
+ |
|
671 |
+ for (i = 0; i < *numFolders; i++) |
|
672 |
+ { |
|
673 |
+ UInt32 j; |
|
674 |
+ CSzFolder *folder = (*folders) + i; |
|
675 |
+ UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder); |
|
676 |
+ |
|
677 |
+ MY_ALLOC(UInt64, folder->UnpackSizes, (size_t)numOutStreams, alloc); |
|
678 |
+ |
|
679 |
+ for (j = 0; j < numOutStreams; j++) |
|
680 |
+ { |
|
681 |
+ RINOK(SzReadNumber(sd, folder->UnpackSizes + j)); |
|
682 |
+ } |
|
683 |
+ } |
|
684 |
+ |
|
685 |
+ for (;;) |
|
686 |
+ { |
|
687 |
+ UInt64 type; |
|
688 |
+ RINOK(SzReadID(sd, &type)); |
|
689 |
+ if (type == k7zIdEnd) |
|
690 |
+ return SZ_OK; |
|
691 |
+ if (type == k7zIdCRC) |
|
692 |
+ { |
|
693 |
+ SRes res; |
|
694 |
+ Byte *crcsDefined = 0; |
|
695 |
+ UInt32 *crcs = 0; |
|
696 |
+ res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp); |
|
697 |
+ if (res == SZ_OK) |
|
698 |
+ { |
|
699 |
+ for (i = 0; i < *numFolders; i++) |
|
700 |
+ { |
|
701 |
+ CSzFolder *folder = (*folders) + i; |
|
702 |
+ folder->UnpackCRCDefined = crcsDefined[i]; |
|
703 |
+ folder->UnpackCRC = crcs[i]; |
|
704 |
+ } |
|
705 |
+ } |
|
706 |
+ IAlloc_Free(allocTemp, crcs); |
|
707 |
+ IAlloc_Free(allocTemp, crcsDefined); |
|
708 |
+ RINOK(res); |
|
709 |
+ continue; |
|
710 |
+ } |
|
711 |
+ RINOK(SzSkeepData(sd)); |
|
712 |
+ } |
|
713 |
+} |
|
714 |
+ |
|
715 |
+static SRes SzReadSubStreamsInfo( |
|
716 |
+ CSzData *sd, |
|
717 |
+ UInt32 numFolders, |
|
718 |
+ CSzFolder *folders, |
|
719 |
+ UInt32 *numUnpackStreams, |
|
720 |
+ UInt64 **unpackSizes, |
|
721 |
+ Byte **digestsDefined, |
|
722 |
+ UInt32 **digests, |
|
723 |
+ ISzAlloc *allocTemp) |
|
724 |
+{ |
|
725 |
+ UInt64 type = 0; |
|
726 |
+ UInt32 i; |
|
727 |
+ UInt32 si = 0; |
|
728 |
+ UInt32 numDigests = 0; |
|
729 |
+ |
|
730 |
+ for (i = 0; i < numFolders; i++) |
|
731 |
+ folders[i].NumUnpackStreams = 1; |
|
732 |
+ *numUnpackStreams = numFolders; |
|
733 |
+ |
|
734 |
+ for (;;) |
|
735 |
+ { |
|
736 |
+ RINOK(SzReadID(sd, &type)); |
|
737 |
+ if (type == k7zIdNumUnpackStream) |
|
738 |
+ { |
|
739 |
+ *numUnpackStreams = 0; |
|
740 |
+ for (i = 0; i < numFolders; i++) |
|
741 |
+ { |
|
742 |
+ UInt32 numStreams; |
|
743 |
+ RINOK(SzReadNumber32(sd, &numStreams)); |
|
744 |
+ folders[i].NumUnpackStreams = numStreams; |
|
745 |
+ *numUnpackStreams += numStreams; |
|
746 |
+ } |
|
747 |
+ continue; |
|
748 |
+ } |
|
749 |
+ if (type == k7zIdCRC || type == k7zIdSize) |
|
750 |
+ break; |
|
751 |
+ if (type == k7zIdEnd) |
|
752 |
+ break; |
|
753 |
+ RINOK(SzSkeepData(sd)); |
|
754 |
+ } |
|
755 |
+ |
|
756 |
+ if (*numUnpackStreams == 0) |
|
757 |
+ { |
|
758 |
+ *unpackSizes = 0; |
|
759 |
+ *digestsDefined = 0; |
|
760 |
+ *digests = 0; |
|
761 |
+ } |
|
762 |
+ else |
|
763 |
+ { |
|
764 |
+ *unpackSizes = (UInt64 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt64)); |
|
765 |
+ RINOM(*unpackSizes); |
|
766 |
+ *digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(Byte)); |
|
767 |
+ RINOM(*digestsDefined); |
|
768 |
+ *digests = (UInt32 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt32)); |
|
769 |
+ RINOM(*digests); |
|
770 |
+ } |
|
771 |
+ |
|
772 |
+ for (i = 0; i < numFolders; i++) |
|
773 |
+ { |
|
774 |
+ /* |
|
775 |
+ v3.13 incorrectly worked with empty folders |
|
776 |
+ v4.07: we check that folder is empty |
|
777 |
+ */ |
|
778 |
+ UInt64 sum = 0; |
|
779 |
+ UInt32 j; |
|
780 |
+ UInt32 numSubstreams = folders[i].NumUnpackStreams; |
|
781 |
+ if (numSubstreams == 0) |
|
782 |
+ continue; |
|
783 |
+ if (type == k7zIdSize) |
|
784 |
+ for (j = 1; j < numSubstreams; j++) |
|
785 |
+ { |
|
786 |
+ UInt64 size; |
|
787 |
+ RINOK(SzReadNumber(sd, &size)); |
|
788 |
+ (*unpackSizes)[si++] = size; |
|
789 |
+ sum += size; |
|
790 |
+ } |
|
791 |
+ (*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum; |
|
792 |
+ } |
|
793 |
+ if (type == k7zIdSize) |
|
794 |
+ { |
|
795 |
+ RINOK(SzReadID(sd, &type)); |
|
796 |
+ } |
|
797 |
+ |
|
798 |
+ for (i = 0; i < *numUnpackStreams; i++) |
|
799 |
+ { |
|
800 |
+ (*digestsDefined)[i] = 0; |
|
801 |
+ (*digests)[i] = 0; |
|
802 |
+ } |
|
803 |
+ |
|
804 |
+ |
|
805 |
+ for (i = 0; i < numFolders; i++) |
|
806 |
+ { |
|
807 |
+ UInt32 numSubstreams = folders[i].NumUnpackStreams; |
|
808 |
+ if (numSubstreams != 1 || !folders[i].UnpackCRCDefined) |
|
809 |
+ numDigests += numSubstreams; |
|
810 |
+ } |
|
811 |
+ |
|
812 |
+ |
|
813 |
+ si = 0; |
|
814 |
+ for (;;) |
|
815 |
+ { |
|
816 |
+ if (type == k7zIdCRC) |
|
817 |
+ { |
|
818 |
+ int digestIndex = 0; |
|
819 |
+ Byte *digestsDefined2 = 0; |
|
820 |
+ UInt32 *digests2 = 0; |
|
821 |
+ SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp); |
|
822 |
+ if (res == SZ_OK) |
|
823 |
+ { |
|
824 |
+ for (i = 0; i < numFolders; i++) |
|
825 |
+ { |
|
826 |
+ CSzFolder *folder = folders + i; |
|
827 |
+ UInt32 numSubstreams = folder->NumUnpackStreams; |
|
828 |
+ if (numSubstreams == 1 && folder->UnpackCRCDefined) |
|
829 |
+ { |
|
830 |
+ (*digestsDefined)[si] = 1; |
|
831 |
+ (*digests)[si] = folder->UnpackCRC; |
|
832 |
+ si++; |
|
833 |
+ } |
|
834 |
+ else |
|
835 |
+ { |
|
836 |
+ UInt32 j; |
|
837 |
+ for (j = 0; j < numSubstreams; j++, digestIndex++) |
|
838 |
+ { |
|
839 |
+ (*digestsDefined)[si] = digestsDefined2[digestIndex]; |
|
840 |
+ (*digests)[si] = digests2[digestIndex]; |
|
841 |
+ si++; |
|
842 |
+ } |
|
843 |
+ } |
|
844 |
+ } |
|
845 |
+ } |
|
846 |
+ IAlloc_Free(allocTemp, digestsDefined2); |
|
847 |
+ IAlloc_Free(allocTemp, digests2); |
|
848 |
+ RINOK(res); |
|
849 |
+ } |
|
850 |
+ else if (type == k7zIdEnd) |
|
851 |
+ return SZ_OK; |
|
852 |
+ else |
|
853 |
+ { |
|
854 |
+ RINOK(SzSkeepData(sd)); |
|
855 |
+ } |
|
856 |
+ RINOK(SzReadID(sd, &type)); |
|
857 |
+ } |
|
858 |
+} |
|
859 |
+ |
|
860 |
+ |
|
861 |
+static SRes SzReadStreamsInfo( |
|
862 |
+ CSzData *sd, |
|
863 |
+ UInt64 *dataOffset, |
|
864 |
+ CSzAr *p, |
|
865 |
+ UInt32 *numUnpackStreams, |
|
866 |
+ UInt64 **unpackSizes, /* allocTemp */ |
|
867 |
+ Byte **digestsDefined, /* allocTemp */ |
|
868 |
+ UInt32 **digests, /* allocTemp */ |
|
869 |
+ ISzAlloc *alloc, |
|
870 |
+ ISzAlloc *allocTemp) |
|
871 |
+{ |
|
872 |
+ for (;;) |
|
873 |
+ { |
|
874 |
+ UInt64 type; |
|
875 |
+ RINOK(SzReadID(sd, &type)); |
|
876 |
+ if ((UInt64)(int)type != type) |
|
877 |
+ return SZ_ERROR_UNSUPPORTED; |
|
878 |
+ switch((int)type) |
|
879 |
+ { |
|
880 |
+ case k7zIdEnd: |
|
881 |
+ return SZ_OK; |
|
882 |
+ case k7zIdPackInfo: |
|
883 |
+ { |
|
884 |
+ RINOK(SzReadPackInfo(sd, dataOffset, &p->NumPackStreams, |
|
885 |
+ &p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc)); |
|
886 |
+ break; |
|
887 |
+ } |
|
888 |
+ case k7zIdUnpackInfo: |
|
889 |
+ { |
|
890 |
+ RINOK(SzReadUnpackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp)); |
|
891 |
+ break; |
|
892 |
+ } |
|
893 |
+ case k7zIdSubStreamsInfo: |
|
894 |
+ { |
|
895 |
+ RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders, |
|
896 |
+ numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp)); |
|
897 |
+ break; |
|
898 |
+ } |
|
899 |
+ default: |
|
900 |
+ return SZ_ERROR_UNSUPPORTED; |
|
901 |
+ } |
|
902 |
+ } |
|
903 |
+} |
|
904 |
+ |
|
905 |
+size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest) |
|
906 |
+{ |
|
907 |
+ size_t len = p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex]; |
|
908 |
+ if (dest != 0) |
|
909 |
+ { |
|
910 |
+ size_t i; |
|
911 |
+ const Byte *src = p->FileNames.data + (p->FileNameOffsets[fileIndex] * 2); |
|
912 |
+ for (i = 0; i < len; i++) |
|
913 |
+ dest[i] = GetUi16(src + i * 2); |
|
914 |
+ } |
|
915 |
+ return len; |
|
916 |
+} |
|
917 |
+ |
|
918 |
+static SRes SzReadFileNames(const Byte *p, size_t size, UInt32 numFiles, size_t *sizes) |
|
919 |
+{ |
|
920 |
+ UInt32 i; |
|
921 |
+ size_t pos = 0; |
|
922 |
+ for (i = 0; i < numFiles; i++) |
|
923 |
+ { |
|
924 |
+ sizes[i] = pos; |
|
925 |
+ for (;;) |
|
926 |
+ { |
|
927 |
+ if (pos >= size) |
|
928 |
+ return SZ_ERROR_ARCHIVE; |
|
929 |
+ if (p[pos * 2] == 0 && p[pos * 2 + 1] == 0) |
|
930 |
+ break; |
|
931 |
+ pos++; |
|
932 |
+ } |
|
933 |
+ pos++; |
|
934 |
+ } |
|
935 |
+ sizes[i] = pos; |
|
936 |
+ return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE; |
|
937 |
+} |
|
938 |
+ |
|
939 |
+static SRes SzReadHeader2( |
|
940 |
+ CSzArEx *p, /* allocMain */ |
|
941 |
+ CSzData *sd, |
|
942 |
+ UInt64 **unpackSizes, /* allocTemp */ |
|
943 |
+ Byte **digestsDefined, /* allocTemp */ |
|
944 |
+ UInt32 **digests, /* allocTemp */ |
|
945 |
+ Byte **emptyStreamVector, /* allocTemp */ |
|
946 |
+ Byte **emptyFileVector, /* allocTemp */ |
|
947 |
+ Byte **lwtVector, /* allocTemp */ |
|
948 |
+ ISzAlloc *allocMain, |
|
949 |
+ ISzAlloc *allocTemp) |
|
950 |
+{ |
|
951 |
+ UInt64 type; |
|
952 |
+ UInt32 numUnpackStreams = 0; |
|
953 |
+ UInt32 numFiles = 0; |
|
954 |
+ CSzFileItem *files = 0; |
|
955 |
+ UInt32 numEmptyStreams = 0; |
|
956 |
+ UInt32 i; |
|
957 |
+ |
|
958 |
+ RINOK(SzReadID(sd, &type)); |
|
959 |
+ |
|
960 |
+ if (type == k7zIdArchiveProperties) |
|
961 |
+ { |
|
962 |
+ RINOK(SzReadArchiveProperties(sd)); |
|
963 |
+ RINOK(SzReadID(sd, &type)); |
|
964 |
+ } |
|
965 |
+ |
|
966 |
+ |
|
967 |
+ if (type == k7zIdMainStreamsInfo) |
|
968 |
+ { |
|
969 |
+ RINOK(SzReadStreamsInfo(sd, |
|
970 |
+ &p->dataPos, |
|
971 |
+ &p->db, |
|
972 |
+ &numUnpackStreams, |
|
973 |
+ unpackSizes, |
|
974 |
+ digestsDefined, |
|
975 |
+ digests, allocMain, allocTemp)); |
|
976 |
+ p->dataPos += p->startPosAfterHeader; |
|
977 |
+ RINOK(SzReadID(sd, &type)); |
|
978 |
+ } |
|
979 |
+ |
|
980 |
+ if (type == k7zIdEnd) |
|
981 |
+ return SZ_OK; |
|
982 |
+ if (type != k7zIdFilesInfo) |
|
983 |
+ return SZ_ERROR_ARCHIVE; |
|
984 |
+ |
|
985 |
+ RINOK(SzReadNumber32(sd, &numFiles)); |
|
986 |
+ p->db.NumFiles = numFiles; |
|
987 |
+ |
|
988 |
+ MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain); |
|
989 |
+ |
|
990 |
+ p->db.Files = files; |
|
991 |
+ for (i = 0; i < numFiles; i++) |
|
992 |
+ SzFile_Init(files + i); |
|
993 |
+ |
|
994 |
+ for (;;) |
|
995 |
+ { |
|
996 |
+ UInt64 type; |
|
997 |
+ UInt64 size; |
|
998 |
+ RINOK(SzReadID(sd, &type)); |
|
999 |
+ if (type == k7zIdEnd) |
|
1000 |
+ break; |
|
1001 |
+ RINOK(SzReadNumber(sd, &size)); |
|
1002 |
+ if (size > sd->Size) |
|
1003 |
+ return SZ_ERROR_ARCHIVE; |
|
1004 |
+ if ((UInt64)(int)type != type) |
|
1005 |
+ { |
|
1006 |
+ RINOK(SzSkeepDataSize(sd, size)); |
|
1007 |
+ } |
|
1008 |
+ else |
|
1009 |
+ switch((int)type) |
|
1010 |
+ { |
|
1011 |
+ case k7zIdName: |
|
1012 |
+ { |
|
1013 |
+ size_t namesSize; |
|
1014 |
+ RINOK(SzReadSwitch(sd)); |
|
1015 |
+ namesSize = (size_t)size - 1; |
|
1016 |
+ if ((namesSize & 1) != 0) |
|
1017 |
+ return SZ_ERROR_ARCHIVE; |
|
1018 |
+ if (!Buf_Create(&p->FileNames, namesSize, allocMain)) |
|
1019 |
+ return SZ_ERROR_MEM; |
|
1020 |
+ MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain); |
|
1021 |
+ memcpy(p->FileNames.data, sd->Data, namesSize); |
|
1022 |
+ RINOK(SzReadFileNames(sd->Data, namesSize >> 1, numFiles, p->FileNameOffsets)) |
|
1023 |
+ RINOK(SzSkeepDataSize(sd, namesSize)); |
|
1024 |
+ break; |
|
1025 |
+ } |
|
1026 |
+ case k7zIdEmptyStream: |
|
1027 |
+ { |
|
1028 |
+ RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp)); |
|
1029 |
+ numEmptyStreams = 0; |
|
1030 |
+ for (i = 0; i < numFiles; i++) |
|
1031 |
+ if ((*emptyStreamVector)[i]) |
|
1032 |
+ numEmptyStreams++; |
|
1033 |
+ break; |
|
1034 |
+ } |
|
1035 |
+ case k7zIdEmptyFile: |
|
1036 |
+ { |
|
1037 |
+ RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp)); |
|
1038 |
+ break; |
|
1039 |
+ } |
|
1040 |
+ case k7zIdWinAttributes: |
|
1041 |
+ { |
|
1042 |
+ RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp)); |
|
1043 |
+ RINOK(SzReadSwitch(sd)); |
|
1044 |
+ for (i = 0; i < numFiles; i++) |
|
1045 |
+ { |
|
1046 |
+ CSzFileItem *f = &files[i]; |
|
1047 |
+ Byte defined = (*lwtVector)[i]; |
|
1048 |
+ f->AttribDefined = defined; |
|
1049 |
+ f->Attrib = 0; |
|
1050 |
+ if (defined) |
|
1051 |
+ { |
|
1052 |
+ RINOK(SzReadUInt32(sd, &f->Attrib)); |
|
1053 |
+ } |
|
1054 |
+ } |
|
1055 |
+ IAlloc_Free(allocTemp, *lwtVector); |
|
1056 |
+ *lwtVector = NULL; |
|
1057 |
+ break; |
|
1058 |
+ } |
|
1059 |
+ case k7zIdMTime: |
|
1060 |
+ { |
|
1061 |
+ RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp)); |
|
1062 |
+ RINOK(SzReadSwitch(sd)); |
|
1063 |
+ for (i = 0; i < numFiles; i++) |
|
1064 |
+ { |
|
1065 |
+ CSzFileItem *f = &files[i]; |
|
1066 |
+ Byte defined = (*lwtVector)[i]; |
|
1067 |
+ f->MTimeDefined = defined; |
|
1068 |
+ f->MTime.Low = f->MTime.High = 0; |
|
1069 |
+ if (defined) |
|
1070 |
+ { |
|
1071 |
+ RINOK(SzReadUInt32(sd, &f->MTime.Low)); |
|
1072 |
+ RINOK(SzReadUInt32(sd, &f->MTime.High)); |
|
1073 |
+ } |
|
1074 |
+ } |
|
1075 |
+ IAlloc_Free(allocTemp, *lwtVector); |
|
1076 |
+ *lwtVector = NULL; |
|
1077 |
+ break; |
|
1078 |
+ } |
|
1079 |
+ default: |
|
1080 |
+ { |
|
1081 |
+ RINOK(SzSkeepDataSize(sd, size)); |
|
1082 |
+ } |
|
1083 |
+ } |
|
1084 |
+ } |
|
1085 |
+ |
|
1086 |
+ { |
|
1087 |
+ UInt32 emptyFileIndex = 0; |
|
1088 |
+ UInt32 sizeIndex = 0; |
|
1089 |
+ for (i = 0; i < numFiles; i++) |
|
1090 |
+ { |
|
1091 |
+ CSzFileItem *file = files + i; |
|
1092 |
+ file->IsAnti = 0; |
|
1093 |
+ if (*emptyStreamVector == 0) |
|
1094 |
+ file->HasStream = 1; |
|
1095 |
+ else |
|
1096 |
+ file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1); |
|
1097 |
+ if (file->HasStream) |
|
1098 |
+ { |
|
1099 |
+ file->IsDir = 0; |
|
1100 |
+ file->Size = (*unpackSizes)[sizeIndex]; |
|
1101 |
+ file->Crc = (*digests)[sizeIndex]; |
|
1102 |
+ file->CrcDefined = (Byte)(*digestsDefined)[sizeIndex]; |
|
1103 |
+ sizeIndex++; |
|
1104 |
+ } |
|
1105 |
+ else |
|
1106 |
+ { |
|
1107 |
+ if (*emptyFileVector == 0) |
|
1108 |
+ file->IsDir = 1; |
|
1109 |
+ else |
|
1110 |
+ file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1); |
|
1111 |
+ emptyFileIndex++; |
|
1112 |
+ file->Size = 0; |
|
1113 |
+ file->Crc = 0; |
|
1114 |
+ file->CrcDefined = 0; |
|
1115 |
+ } |
|
1116 |
+ } |
|
1117 |
+ } |
|
1118 |
+ return SzArEx_Fill(p, allocMain); |
|
1119 |
+} |
|
1120 |
+ |
|
1121 |
+static SRes SzReadHeader( |
|
1122 |
+ CSzArEx *p, |
|
1123 |
+ CSzData *sd, |
|
1124 |
+ ISzAlloc *allocMain, |
|
1125 |
+ ISzAlloc *allocTemp) |
|
1126 |
+{ |
|
1127 |
+ UInt64 *unpackSizes = 0; |
|
1128 |
+ Byte *digestsDefined = 0; |
|
1129 |
+ UInt32 *digests = 0; |
|
1130 |
+ Byte *emptyStreamVector = 0; |
|
1131 |
+ Byte *emptyFileVector = 0; |
|
1132 |
+ Byte *lwtVector = 0; |
|
1133 |
+ SRes res = SzReadHeader2(p, sd, |
|
1134 |
+ &unpackSizes, &digestsDefined, &digests, |
|
1135 |
+ &emptyStreamVector, &emptyFileVector, &lwtVector, |
|
1136 |
+ allocMain, allocTemp); |
|
1137 |
+ IAlloc_Free(allocTemp, unpackSizes); |
|
1138 |
+ IAlloc_Free(allocTemp, digestsDefined); |
|
1139 |
+ IAlloc_Free(allocTemp, digests); |
|
1140 |
+ IAlloc_Free(allocTemp, emptyStreamVector); |
|
1141 |
+ IAlloc_Free(allocTemp, emptyFileVector); |
|
1142 |
+ IAlloc_Free(allocTemp, lwtVector); |
|
1143 |
+ return res; |
|
1144 |
+} |
|
1145 |
+ |
|
1146 |
+static SRes SzReadAndDecodePackedStreams2( |
|
1147 |
+ ILookInStream *inStream, |
|
1148 |
+ CSzData *sd, |
|
1149 |
+ CBuf *outBuffer, |
|
1150 |
+ UInt64 baseOffset, |
|
1151 |
+ CSzAr *p, |
|
1152 |
+ UInt64 **unpackSizes, |
|
1153 |
+ Byte **digestsDefined, |
|
1154 |
+ UInt32 **digests, |
|
1155 |
+ ISzAlloc *allocTemp) |
|
1156 |
+{ |
|
1157 |
+ |
|
1158 |
+ UInt32 numUnpackStreams = 0; |
|
1159 |
+ UInt64 dataStartPos; |
|
1160 |
+ CSzFolder *folder; |
|
1161 |
+ UInt64 unpackSize; |
|
1162 |
+ SRes res; |
|
1163 |
+ |
|
1164 |
+ RINOK(SzReadStreamsInfo(sd, &dataStartPos, p, |
|
1165 |
+ &numUnpackStreams, unpackSizes, digestsDefined, digests, |
|
1166 |
+ allocTemp, allocTemp)); |
|
1167 |
+ |
|
1168 |
+ dataStartPos += baseOffset; |
|
1169 |
+ if (p->NumFolders != 1) |
|
1170 |
+ return SZ_ERROR_ARCHIVE; |
|
1171 |
+ |
|
1172 |
+ folder = p->Folders; |
|
1173 |
+ unpackSize = SzFolder_GetUnpackSize(folder); |
|
1174 |
+ |
|
1175 |
+ RINOK(LookInStream_SeekTo(inStream, dataStartPos)); |
|
1176 |
+ |
|
1177 |
+ if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp)) |
|
1178 |
+ return SZ_ERROR_MEM; |
|
1179 |
+ |
|
1180 |
+ res = SzFolder_Decode(folder, p->PackSizes, |
|
1181 |
+ inStream, dataStartPos, |
|
1182 |
+ outBuffer->data, (size_t)unpackSize, allocTemp); |
|
1183 |
+ RINOK(res); |
|
1184 |
+ if (folder->UnpackCRCDefined) |
|
1185 |
+ if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC) |
|
1186 |
+ return SZ_ERROR_CRC; |
|
1187 |
+ return SZ_OK; |
|
1188 |
+} |
|
1189 |
+ |
|
1190 |
+static SRes SzReadAndDecodePackedStreams( |
|
1191 |
+ ILookInStream *inStream, |
|
1192 |
+ CSzData *sd, |
|
1193 |
+ CBuf *outBuffer, |
|
1194 |
+ UInt64 baseOffset, |
|
1195 |
+ ISzAlloc *allocTemp) |
|
1196 |
+{ |
|
1197 |
+ CSzAr p; |
|
1198 |
+ UInt64 *unpackSizes = 0; |
|
1199 |
+ Byte *digestsDefined = 0; |
|
1200 |
+ UInt32 *digests = 0; |
|
1201 |
+ SRes res; |
|
1202 |
+ SzAr_Init(&p); |
|
1203 |
+ res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset, |
|
1204 |
+ &p, &unpackSizes, &digestsDefined, &digests, |
|
1205 |
+ allocTemp); |
|
1206 |
+ SzAr_Free(&p, allocTemp); |
|
1207 |
+ IAlloc_Free(allocTemp, unpackSizes); |
|
1208 |
+ IAlloc_Free(allocTemp, digestsDefined); |
|
1209 |
+ IAlloc_Free(allocTemp, digests); |
|
1210 |
+ return res; |
|
1211 |
+} |
|
1212 |
+ |
|
1213 |
+static SRes SzArEx_Open2( |
|
1214 |
+ CSzArEx *p, |
|
1215 |
+ ILookInStream *inStream, |
|
1216 |
+ ISzAlloc *allocMain, |
|
1217 |
+ ISzAlloc *allocTemp) |
|
1218 |
+{ |
|
1219 |
+ Byte header[k7zStartHeaderSize]; |
|
1220 |
+ Int64 startArcPos; |
|
1221 |
+ UInt64 nextHeaderOffset, nextHeaderSize; |
|
1222 |
+ size_t nextHeaderSizeT; |
|
1223 |
+ UInt32 nextHeaderCRC; |
|
1224 |
+ CBuf buffer; |
|
1225 |
+ SRes res; |
|
1226 |
+ |
|
1227 |
+ startArcPos = 0; |
|
1228 |
+ RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR)); |
|
1229 |
+ |
|
1230 |
+ RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE)); |
|
1231 |
+ |
|
1232 |
+ if (!TestSignatureCandidate(header)) |
|
1233 |
+ return SZ_ERROR_NO_ARCHIVE; |
|
1234 |
+ if (header[6] != k7zMajorVersion) |
|
1235 |
+ return SZ_ERROR_UNSUPPORTED; |
|
1236 |
+ |
|
1237 |
+ nextHeaderOffset = GetUi64(header + 12); |
|
1238 |
+ nextHeaderSize = GetUi64(header + 20); |
|
1239 |
+ nextHeaderCRC = GetUi32(header + 28); |
|
1240 |
+ |
|
1241 |
+ p->startPosAfterHeader = startArcPos + k7zStartHeaderSize; |
|
1242 |
+ |
|
1243 |
+ if (CrcCalc(header + 12, 20) != GetUi32(header + 8)) |
|
1244 |
+ return SZ_ERROR_CRC; |
|
1245 |
+ |
|
1246 |
+ nextHeaderSizeT = (size_t)nextHeaderSize; |
|
1247 |
+ if (nextHeaderSizeT != nextHeaderSize) |
|
1248 |
+ return SZ_ERROR_MEM; |
|
1249 |
+ if (nextHeaderSizeT == 0) |
|
1250 |
+ return SZ_OK; |
|
1251 |
+ if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize || |
|
1252 |
+ nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize) |
|
1253 |
+ return SZ_ERROR_NO_ARCHIVE; |
|
1254 |
+ |
|
1255 |
+ { |
|
1256 |
+ Int64 pos = 0; |
|
1257 |
+ RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END)); |
|
1258 |
+ if ((UInt64)pos < startArcPos + nextHeaderOffset || |
|
1259 |
+ (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset || |
|
1260 |
+ (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize) |
|
1261 |
+ return SZ_ERROR_INPUT_EOF; |
|
1262 |
+ } |
|
1263 |
+ |
|
1264 |
+ RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset)); |
|
1265 |
+ |
|
1266 |
+ if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp)) |
|
1267 |
+ return SZ_ERROR_MEM; |
|
1268 |
+ |
|
1269 |
+ res = LookInStream_Read(inStream, buffer.data, nextHeaderSizeT); |
|
1270 |
+ if (res == SZ_OK) |
|
1271 |
+ { |
|
1272 |
+ res = SZ_ERROR_ARCHIVE; |
|
1273 |
+ if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC) |
|
1274 |
+ { |
|
1275 |
+ CSzData sd; |
|
1276 |
+ UInt64 type; |
|
1277 |
+ sd.Data = buffer.data; |
|
1278 |
+ sd.Size = buffer.size; |
|
1279 |
+ res = SzReadID(&sd, &type); |
|
1280 |
+ if (res == SZ_OK) |
|
1281 |
+ { |
|
1282 |
+ if (type == k7zIdEncodedHeader) |
|
1283 |
+ { |
|
1284 |
+ CBuf outBuffer; |
|
1285 |
+ Buf_Init(&outBuffer); |
|
1286 |
+ res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, p->startPosAfterHeader, allocTemp); |
|
1287 |
+ if (res != SZ_OK) |
|
1288 |
+ Buf_Free(&outBuffer, allocTemp); |
|
1289 |
+ else |
|
1290 |
+ { |
|
1291 |
+ Buf_Free(&buffer, allocTemp); |
|
1292 |
+ buffer.data = outBuffer.data; |
|
1293 |
+ buffer.size = outBuffer.size; |
|
1294 |
+ sd.Data = buffer.data; |
|
1295 |
+ sd.Size = buffer.size; |
|
1296 |
+ res = SzReadID(&sd, &type); |
|
1297 |
+ } |
|
1298 |
+ } |
|
1299 |
+ } |
|
1300 |
+ if (res == SZ_OK) |
|
1301 |
+ { |
|
1302 |
+ if (type == k7zIdHeader) |
|
1303 |
+ res = SzReadHeader(p, &sd, allocMain, allocTemp); |
|
1304 |
+ else |
|
1305 |
+ res = SZ_ERROR_UNSUPPORTED; |
|
1306 |
+ } |
|
1307 |
+ } |
|
1308 |
+ } |
|
1309 |
+ Buf_Free(&buffer, allocTemp); |
|
1310 |
+ return res; |
|
1311 |
+} |
|
1312 |
+ |
|
1313 |
+SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp) |
|
1314 |
+{ |
|
1315 |
+ SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp); |
|
1316 |
+ if (res != SZ_OK) |
|
1317 |
+ SzArEx_Free(p, allocMain); |
|
1318 |
+ return res; |
|
1319 |
+} |
|
1320 |
+ |
|
1321 |
+SRes SzArEx_Extract( |
|
1322 |
+ const CSzArEx *p, |
|
1323 |
+ ILookInStream *inStream, |
|
1324 |
+ UInt32 fileIndex, |
|
1325 |
+ UInt32 *blockIndex, |
|
1326 |
+ Byte **outBuffer, |
|
1327 |
+ size_t *outBufferSize, |
|
1328 |
+ size_t *offset, |
|
1329 |
+ size_t *outSizeProcessed, |
|
1330 |
+ ISzAlloc *allocMain, |
|
1331 |
+ ISzAlloc *allocTemp) |
|
1332 |
+{ |
|
1333 |
+ UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex]; |
|
1334 |
+ SRes res = SZ_OK; |
|
1335 |
+ *offset = 0; |
|
1336 |
+ *outSizeProcessed = 0; |
|
1337 |
+ if (folderIndex == (UInt32)-1) |
|
1338 |
+ { |
|
1339 |
+ IAlloc_Free(allocMain, *outBuffer); |
|
1340 |
+ *blockIndex = folderIndex; |
|
1341 |
+ *outBuffer = 0; |
|
1342 |
+ *outBufferSize = 0; |
|
1343 |
+ return SZ_OK; |
|
1344 |
+ } |
|
1345 |
+ |
|
1346 |
+ if (*outBuffer == 0 || *blockIndex != folderIndex) |
|
1347 |
+ { |
|
1348 |
+ CSzFolder *folder = p->db.Folders + folderIndex; |
|
1349 |
+ UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder); |
|
1350 |
+ size_t unpackSize = (size_t)unpackSizeSpec; |
|
1351 |
+ UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0); |
|
1352 |
+ |
|
1353 |
+ if (unpackSize != unpackSizeSpec) |
|
1354 |
+ return SZ_ERROR_MEM; |
|
1355 |
+ *blockIndex = folderIndex; |
|
1356 |
+ IAlloc_Free(allocMain, *outBuffer); |
|
1357 |
+ *outBuffer = 0; |
|
1358 |
+ |
|
1359 |
+ RINOK(LookInStream_SeekTo(inStream, startOffset)); |
|
1360 |
+ |
|
1361 |
+ if (res == SZ_OK) |
|
1362 |
+ { |
|
1363 |
+ *outBufferSize = unpackSize; |
|
1364 |
+ if (unpackSize != 0) |
|
1365 |
+ { |
|
1366 |
+ *outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize); |
|
1367 |
+ if (*outBuffer == 0) |
|
1368 |
+ res = SZ_ERROR_MEM; |
|
1369 |
+ } |
|
1370 |
+ if (res == SZ_OK) |
|
1371 |
+ { |
|
1372 |
+ res = SzFolder_Decode(folder, |
|
1373 |
+ p->db.PackSizes + p->FolderStartPackStreamIndex[folderIndex], |
|
1374 |
+ inStream, startOffset, |
|
1375 |
+ *outBuffer, unpackSize, allocTemp); |
|
1376 |
+ if (res == SZ_OK) |
|
1377 |
+ { |
|
1378 |
+ if (folder->UnpackCRCDefined) |
|
1379 |
+ { |
|
1380 |
+ if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC) |
|
1381 |
+ res = SZ_ERROR_CRC; |
|
1382 |
+ } |
|
1383 |
+ } |
|
1384 |
+ } |
|
1385 |
+ } |
|
1386 |
+ } |
|
1387 |
+ if (res == SZ_OK) |
|
1388 |
+ { |
|
1389 |
+ UInt32 i; |
|
1390 |
+ CSzFileItem *fileItem = p->db.Files + fileIndex; |
|
1391 |
+ *offset = 0; |
|
1392 |
+ for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++) |
|
1393 |
+ *offset += (UInt32)p->db.Files[i].Size; |
|
1394 |
+ *outSizeProcessed = (size_t)fileItem->Size; |
|
1395 |
+ if (*offset + *outSizeProcessed > *outBufferSize) |
|
1396 |
+ return SZ_ERROR_FAIL; |
|
1397 |
+ if (fileItem->CrcDefined && CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->Crc) |
|
1398 |
+ res = SZ_ERROR_CRC; |
|
1399 |
+ } |
|
1400 |
+ return res; |
|
1401 |
+} |
... | ... |
@@ -1,169 +1,169 @@ |
1 |
-/* 7zStream.c -- 7z Stream functions |
|
2 |
-2008-11-23 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#include <string.h> |
|
5 |
- |
|
6 |
-#include "Types.h" |
|
7 |
- |
|
8 |
-SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType) |
|
9 |
-{ |
|
10 |
- while (size != 0) |
|
11 |
- { |
|
12 |
- size_t processed = size; |
|
13 |
- RINOK(stream->Read(stream, buf, &processed)); |
|
14 |
- if (processed == 0) |
|
15 |
- return errorType; |
|
16 |
- buf = (void *)((Byte *)buf + processed); |
|
17 |
- size -= processed; |
|
18 |
- } |
|
19 |
- return SZ_OK; |
|
20 |
-} |
|
21 |
- |
|
22 |
-SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size) |
|
23 |
-{ |
|
24 |
- return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); |
|
25 |
-} |
|
26 |
- |
|
27 |
-SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf) |
|
28 |
-{ |
|
29 |
- size_t processed = 1; |
|
30 |
- RINOK(stream->Read(stream, buf, &processed)); |
|
31 |
- return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF; |
|
32 |
-} |
|
33 |
- |
|
34 |
-SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset) |
|
35 |
-{ |
|
36 |
- Int64 t = offset; |
|
37 |
- return stream->Seek(stream, &t, SZ_SEEK_SET); |
|
38 |
-} |
|
39 |
- |
|
40 |
-SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size) |
|
41 |
-{ |
|
42 |
- void *lookBuf; |
|
43 |
- if (*size == 0) |
|
44 |
- return SZ_OK; |
|
45 |
- RINOK(stream->Look(stream, &lookBuf, size)); |
|
46 |
- memcpy(buf, lookBuf, *size); |
|
47 |
- return stream->Skip(stream, *size); |
|
48 |
-} |
|
49 |
- |
|
50 |
-SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType) |
|
51 |
-{ |
|
52 |
- while (size != 0) |
|
53 |
- { |
|
54 |
- size_t processed = size; |
|
55 |
- RINOK(stream->Read(stream, buf, &processed)); |
|
56 |
- if (processed == 0) |
|
57 |
- return errorType; |
|
58 |
- buf = (void *)((Byte *)buf + processed); |
|
59 |
- size -= processed; |
|
60 |
- } |
|
61 |
- return SZ_OK; |
|
62 |
-} |
|
63 |
- |
|
64 |
-SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size) |
|
65 |
-{ |
|
66 |
- return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); |
|
67 |
-} |
|
68 |
- |
|
69 |
-static SRes LookToRead_Look_Lookahead(void *pp, void **buf, size_t *size) |
|
70 |
-{ |
|
71 |
- SRes res = SZ_OK; |
|
72 |
- CLookToRead *p = (CLookToRead *)pp; |
|
73 |
- size_t size2 = p->size - p->pos; |
|
74 |
- if (size2 == 0 && *size > 0) |
|
75 |
- { |
|
76 |
- p->pos = 0; |
|
77 |
- size2 = LookToRead_BUF_SIZE; |
|
78 |
- res = p->realStream->Read(p->realStream, p->buf, &size2); |
|
79 |
- p->size = size2; |
|
80 |
- } |
|
81 |
- if (size2 < *size) |
|
82 |
- *size = size2; |
|
83 |
- *buf = p->buf + p->pos; |
|
84 |
- return res; |
|
85 |
-} |
|
86 |
- |
|
87 |
-static SRes LookToRead_Look_Exact(void *pp, void **buf, size_t *size) |
|
88 |
-{ |
|
89 |
- SRes res = SZ_OK; |
|
90 |
- CLookToRead *p = (CLookToRead *)pp; |
|
91 |
- size_t size2 = p->size - p->pos; |
|
92 |
- if (size2 == 0 && *size > 0) |
|
93 |
- { |
|
94 |
- p->pos = 0; |
|
95 |
- if (*size > LookToRead_BUF_SIZE) |
|
96 |
- *size = LookToRead_BUF_SIZE; |
|
97 |
- res = p->realStream->Read(p->realStream, p->buf, size); |
|
98 |
- size2 = p->size = *size; |
|
99 |
- } |
|
100 |
- if (size2 < *size) |
|
101 |
- *size = size2; |
|
102 |
- *buf = p->buf + p->pos; |
|
103 |
- return res; |
|
104 |
-} |
|
105 |
- |
|
106 |
-static SRes LookToRead_Skip(void *pp, size_t offset) |
|
107 |
-{ |
|
108 |
- CLookToRead *p = (CLookToRead *)pp; |
|
109 |
- p->pos += offset; |
|
110 |
- return SZ_OK; |
|
111 |
-} |
|
112 |
- |
|
113 |
-static SRes LookToRead_Read(void *pp, void *buf, size_t *size) |
|
114 |
-{ |
|
115 |
- CLookToRead *p = (CLookToRead *)pp; |
|
116 |
- size_t rem = p->size - p->pos; |
|
117 |
- if (rem == 0) |
|
118 |
- return p->realStream->Read(p->realStream, buf, size); |
|
119 |
- if (rem > *size) |
|
120 |
- rem = *size; |
|
121 |
- memcpy(buf, p->buf + p->pos, rem); |
|
122 |
- p->pos += rem; |
|
123 |
- *size = rem; |
|
124 |
- return SZ_OK; |
|
125 |
-} |
|
126 |
- |
|
127 |
-static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin) |
|
128 |
-{ |
|
129 |
- CLookToRead *p = (CLookToRead *)pp; |
|
130 |
- p->pos = p->size = 0; |
|
131 |
- return p->realStream->Seek(p->realStream, pos, origin); |
|
132 |
-} |
|
133 |
- |
|
134 |
-void LookToRead_CreateVTable(CLookToRead *p, int lookahead) |
|
135 |
-{ |
|
136 |
- p->s.Look = lookahead ? |
|
137 |
- LookToRead_Look_Lookahead : |
|
138 |
- LookToRead_Look_Exact; |
|
139 |
- p->s.Skip = LookToRead_Skip; |
|
140 |
- p->s.Read = LookToRead_Read; |
|
141 |
- p->s.Seek = LookToRead_Seek; |
|
142 |
-} |
|
143 |
- |
|
144 |
-void LookToRead_Init(CLookToRead *p) |
|
145 |
-{ |
|
146 |
- p->pos = p->size = 0; |
|
147 |
-} |
|
148 |
- |
|
149 |
-static SRes SecToLook_Read(void *pp, void *buf, size_t *size) |
|
150 |
-{ |
|
151 |
- CSecToLook *p = (CSecToLook *)pp; |
|
152 |
- return LookInStream_LookRead(p->realStream, buf, size); |
|
153 |
-} |
|
154 |
- |
|
155 |
-void SecToLook_CreateVTable(CSecToLook *p) |
|
156 |
-{ |
|
157 |
- p->s.Read = SecToLook_Read; |
|
158 |
-} |
|
159 |
- |
|
160 |
-static SRes SecToRead_Read(void *pp, void *buf, size_t *size) |
|
161 |
-{ |
|
162 |
- CSecToRead *p = (CSecToRead *)pp; |
|
163 |
- return p->realStream->Read(p->realStream, buf, size); |
|
164 |
-} |
|
165 |
- |
|
166 |
-void SecToRead_CreateVTable(CSecToRead *p) |
|
167 |
-{ |
|
168 |
- p->s.Read = SecToRead_Read; |
|
169 |
-} |
|
1 |
+/* 7zStream.c -- 7z Stream functions |
|
2 |
+2010-03-11 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#include <string.h> |
|
5 |
+ |
|
6 |
+#include "Types.h" |
|
7 |
+ |
|
8 |
+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType) |
|
9 |
+{ |
|
10 |
+ while (size != 0) |
|
11 |
+ { |
|
12 |
+ size_t processed = size; |
|
13 |
+ RINOK(stream->Read(stream, buf, &processed)); |
|
14 |
+ if (processed == 0) |
|
15 |
+ return errorType; |
|
16 |
+ buf = (void *)((Byte *)buf + processed); |
|
17 |
+ size -= processed; |
|
18 |
+ } |
|
19 |
+ return SZ_OK; |
|
20 |
+} |
|
21 |
+ |
|
22 |
+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size) |
|
23 |
+{ |
|
24 |
+ return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); |
|
25 |
+} |
|
26 |
+ |
|
27 |
+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf) |
|
28 |
+{ |
|
29 |
+ size_t processed = 1; |
|
30 |
+ RINOK(stream->Read(stream, buf, &processed)); |
|
31 |
+ return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF; |
|
32 |
+} |
|
33 |
+ |
|
34 |
+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset) |
|
35 |
+{ |
|
36 |
+ Int64 t = offset; |
|
37 |
+ return stream->Seek(stream, &t, SZ_SEEK_SET); |
|
38 |
+} |
|
39 |
+ |
|
40 |
+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size) |
|
41 |
+{ |
|
42 |
+ const void *lookBuf; |
|
43 |
+ if (*size == 0) |
|
44 |
+ return SZ_OK; |
|
45 |
+ RINOK(stream->Look(stream, &lookBuf, size)); |
|
46 |
+ memcpy(buf, lookBuf, *size); |
|
47 |
+ return stream->Skip(stream, *size); |
|
48 |
+} |
|
49 |
+ |
|
50 |
+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType) |
|
51 |
+{ |
|
52 |
+ while (size != 0) |
|
53 |
+ { |
|
54 |
+ size_t processed = size; |
|
55 |
+ RINOK(stream->Read(stream, buf, &processed)); |
|
56 |
+ if (processed == 0) |
|
57 |
+ return errorType; |
|
58 |
+ buf = (void *)((Byte *)buf + processed); |
|
59 |
+ size -= processed; |
|
60 |
+ } |
|
61 |
+ return SZ_OK; |
|
62 |
+} |
|
63 |
+ |
|
64 |
+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size) |
|
65 |
+{ |
|
66 |
+ return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); |
|
67 |
+} |
|
68 |
+ |
|
69 |
+static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size) |
|
70 |
+{ |
|
71 |
+ SRes res = SZ_OK; |
|
72 |
+ CLookToRead *p = (CLookToRead *)pp; |
|
73 |
+ size_t size2 = p->size - p->pos; |
|
74 |
+ if (size2 == 0 && *size > 0) |
|
75 |
+ { |
|
76 |
+ p->pos = 0; |
|
77 |
+ size2 = LookToRead_BUF_SIZE; |
|
78 |
+ res = p->realStream->Read(p->realStream, p->buf, &size2); |
|
79 |
+ p->size = size2; |
|
80 |
+ } |
|
81 |
+ if (size2 < *size) |
|
82 |
+ *size = size2; |
|
83 |
+ *buf = p->buf + p->pos; |
|
84 |
+ return res; |
|
85 |
+} |
|
86 |
+ |
|
87 |
+static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size) |
|
88 |
+{ |
|
89 |
+ SRes res = SZ_OK; |
|
90 |
+ CLookToRead *p = (CLookToRead *)pp; |
|
91 |
+ size_t size2 = p->size - p->pos; |
|
92 |
+ if (size2 == 0 && *size > 0) |
|
93 |
+ { |
|
94 |
+ p->pos = 0; |
|
95 |
+ if (*size > LookToRead_BUF_SIZE) |
|
96 |
+ *size = LookToRead_BUF_SIZE; |
|
97 |
+ res = p->realStream->Read(p->realStream, p->buf, size); |
|
98 |
+ size2 = p->size = *size; |
|
99 |
+ } |
|
100 |
+ if (size2 < *size) |
|
101 |
+ *size = size2; |
|
102 |
+ *buf = p->buf + p->pos; |
|
103 |
+ return res; |
|
104 |
+} |
|
105 |
+ |
|
106 |
+static SRes LookToRead_Skip(void *pp, size_t offset) |
|
107 |
+{ |
|
108 |
+ CLookToRead *p = (CLookToRead *)pp; |
|
109 |
+ p->pos += offset; |
|
110 |
+ return SZ_OK; |
|
111 |
+} |
|
112 |
+ |
|
113 |
+static SRes LookToRead_Read(void *pp, void *buf, size_t *size) |
|
114 |
+{ |
|
115 |
+ CLookToRead *p = (CLookToRead *)pp; |
|
116 |
+ size_t rem = p->size - p->pos; |
|
117 |
+ if (rem == 0) |
|
118 |
+ return p->realStream->Read(p->realStream, buf, size); |
|
119 |
+ if (rem > *size) |
|
120 |
+ rem = *size; |
|
121 |
+ memcpy(buf, p->buf + p->pos, rem); |
|
122 |
+ p->pos += rem; |
|
123 |
+ *size = rem; |
|
124 |
+ return SZ_OK; |
|
125 |
+} |
|
126 |
+ |
|
127 |
+static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin) |
|
128 |
+{ |
|
129 |
+ CLookToRead *p = (CLookToRead *)pp; |
|
130 |
+ p->pos = p->size = 0; |
|
131 |
+ return p->realStream->Seek(p->realStream, pos, origin); |
|
132 |
+} |
|
133 |
+ |
|
134 |
+void LookToRead_CreateVTable(CLookToRead *p, int lookahead) |
|
135 |
+{ |
|
136 |
+ p->s.Look = lookahead ? |
|
137 |
+ LookToRead_Look_Lookahead : |
|
138 |
+ LookToRead_Look_Exact; |
|
139 |
+ p->s.Skip = LookToRead_Skip; |
|
140 |
+ p->s.Read = LookToRead_Read; |
|
141 |
+ p->s.Seek = LookToRead_Seek; |
|
142 |
+} |
|
143 |
+ |
|
144 |
+void LookToRead_Init(CLookToRead *p) |
|
145 |
+{ |
|
146 |
+ p->pos = p->size = 0; |
|
147 |
+} |
|
148 |
+ |
|
149 |
+static SRes SecToLook_Read(void *pp, void *buf, size_t *size) |
|
150 |
+{ |
|
151 |
+ CSecToLook *p = (CSecToLook *)pp; |
|
152 |
+ return LookInStream_LookRead(p->realStream, buf, size); |
|
153 |
+} |
|
154 |
+ |
|
155 |
+void SecToLook_CreateVTable(CSecToLook *p) |
|
156 |
+{ |
|
157 |
+ p->s.Read = SecToLook_Read; |
|
158 |
+} |
|
159 |
+ |
|
160 |
+static SRes SecToRead_Read(void *pp, void *buf, size_t *size) |
|
161 |
+{ |
|
162 |
+ CSecToRead *p = (CSecToRead *)pp; |
|
163 |
+ return p->realStream->Read(p->realStream, buf, size); |
|
164 |
+} |
|
165 |
+ |
|
166 |
+void SecToRead_CreateVTable(CSecToRead *p) |
|
167 |
+{ |
|
168 |
+ p->s.Read = SecToRead_Read; |
|
169 |
+} |
170 | 170 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,7 @@ |
0 |
+#define MY_VER_MAJOR 9 |
|
1 |
+#define MY_VER_MINOR 20 |
|
2 |
+#define MY_VER_BUILD 0 |
|
3 |
+#define MY_VERSION "9.20" |
|
4 |
+#define MY_DATE "2010-11-18" |
|
5 |
+#define MY_COPYRIGHT ": Igor Pavlov : Public domain" |
|
6 |
+#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE |
0 | 7 |
deleted file mode 100644 |
... | ... |
@@ -1,257 +0,0 @@ |
1 |
-/* 7zDecode.c -- Decoding from 7z folder |
|
2 |
-2008-11-23 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#include <string.h> |
|
5 |
- |
|
6 |
-#include "../../Bcj2.h" |
|
7 |
-#include "../../Bra.h" |
|
8 |
-#include "../../LzmaDec.h" |
|
9 |
-#include "7zDecode.h" |
|
10 |
- |
|
11 |
-#define k_Copy 0 |
|
12 |
-#define k_LZMA 0x30101 |
|
13 |
-#define k_BCJ 0x03030103 |
|
14 |
-#define k_BCJ2 0x0303011B |
|
15 |
- |
|
16 |
-static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, |
|
17 |
- Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) |
|
18 |
-{ |
|
19 |
- CLzmaDec state; |
|
20 |
- SRes res = SZ_OK; |
|
21 |
- |
|
22 |
- LzmaDec_Construct(&state); |
|
23 |
- RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain)); |
|
24 |
- state.dic = outBuffer; |
|
25 |
- state.dicBufSize = outSize; |
|
26 |
- LzmaDec_Init(&state); |
|
27 |
- |
|
28 |
- for (;;) |
|
29 |
- { |
|
30 |
- Byte *inBuf = NULL; |
|
31 |
- size_t lookahead = (1 << 18); |
|
32 |
- if (lookahead > inSize) |
|
33 |
- lookahead = (size_t)inSize; |
|
34 |
- res = inStream->Look((void *)inStream, (void **)&inBuf, &lookahead); |
|
35 |
- if (res != SZ_OK) |
|
36 |
- break; |
|
37 |
- |
|
38 |
- { |
|
39 |
- SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos; |
|
40 |
- ELzmaStatus status; |
|
41 |
- res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); |
|
42 |
- lookahead -= inProcessed; |
|
43 |
- inSize -= inProcessed; |
|
44 |
- if (res != SZ_OK) |
|
45 |
- break; |
|
46 |
- if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos)) |
|
47 |
- { |
|
48 |
- if (state.dicBufSize != outSize || lookahead != 0 || |
|
49 |
- (status != LZMA_STATUS_FINISHED_WITH_MARK && |
|
50 |
- status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) |
|
51 |
- res = SZ_ERROR_DATA; |
|
52 |
- break; |
|
53 |
- } |
|
54 |
- res = inStream->Skip((void *)inStream, inProcessed); |
|
55 |
- if (res != SZ_OK) |
|
56 |
- break; |
|
57 |
- } |
|
58 |
- } |
|
59 |
- |
|
60 |
- LzmaDec_FreeProbs(&state, allocMain); |
|
61 |
- return res; |
|
62 |
-} |
|
63 |
- |
|
64 |
-static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer) |
|
65 |
-{ |
|
66 |
- while (inSize > 0) |
|
67 |
- { |
|
68 |
- void *inBuf; |
|
69 |
- size_t curSize = (1 << 18); |
|
70 |
- if (curSize > inSize) |
|
71 |
- curSize = (size_t)inSize; |
|
72 |
- RINOK(inStream->Look((void *)inStream, (void **)&inBuf, &curSize)); |
|
73 |
- if (curSize == 0) |
|
74 |
- return SZ_ERROR_INPUT_EOF; |
|
75 |
- memcpy(outBuffer, inBuf, curSize); |
|
76 |
- outBuffer += curSize; |
|
77 |
- inSize -= curSize; |
|
78 |
- RINOK(inStream->Skip((void *)inStream, curSize)); |
|
79 |
- } |
|
80 |
- return SZ_OK; |
|
81 |
-} |
|
82 |
- |
|
83 |
-#define IS_UNSUPPORTED_METHOD(m) ((m) != k_Copy && (m) != k_LZMA) |
|
84 |
-#define IS_UNSUPPORTED_CODER(c) (IS_UNSUPPORTED_METHOD(c.MethodID) || c.NumInStreams != 1 || c.NumOutStreams != 1) |
|
85 |
-#define IS_NO_BCJ(c) (c.MethodID != k_BCJ || c.NumInStreams != 1 || c.NumOutStreams != 1) |
|
86 |
-#define IS_NO_BCJ2(c) (c.MethodID != k_BCJ2 || c.NumInStreams != 4 || c.NumOutStreams != 1) |
|
87 |
- |
|
88 |
-SRes CheckSupportedFolder(const CSzFolder *f) |
|
89 |
-{ |
|
90 |
- if (f->NumCoders < 1 || f->NumCoders > 4) |
|
91 |
- return SZ_ERROR_UNSUPPORTED; |
|
92 |
- if (IS_UNSUPPORTED_CODER(f->Coders[0])) |
|
93 |
- return SZ_ERROR_UNSUPPORTED; |
|
94 |
- if (f->NumCoders == 1) |
|
95 |
- { |
|
96 |
- if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0) |
|
97 |
- return SZ_ERROR_UNSUPPORTED; |
|
98 |
- return SZ_OK; |
|
99 |
- } |
|
100 |
- if (f->NumCoders == 2) |
|
101 |
- { |
|
102 |
- if (IS_NO_BCJ(f->Coders[1]) || |
|
103 |
- f->NumPackStreams != 1 || f->PackStreams[0] != 0 || |
|
104 |
- f->NumBindPairs != 1 || |
|
105 |
- f->BindPairs[0].InIndex != 1 || f->BindPairs[0].OutIndex != 0) |
|
106 |
- return SZ_ERROR_UNSUPPORTED; |
|
107 |
- return SZ_OK; |
|
108 |
- } |
|
109 |
- if (f->NumCoders == 4) |
|
110 |
- { |
|
111 |
- if (IS_UNSUPPORTED_CODER(f->Coders[1]) || |
|
112 |
- IS_UNSUPPORTED_CODER(f->Coders[2]) || |
|
113 |
- IS_NO_BCJ2(f->Coders[3])) |
|
114 |
- return SZ_ERROR_UNSUPPORTED; |
|
115 |
- if (f->NumPackStreams != 4 || |
|
116 |
- f->PackStreams[0] != 2 || |
|
117 |
- f->PackStreams[1] != 6 || |
|
118 |
- f->PackStreams[2] != 1 || |
|
119 |
- f->PackStreams[3] != 0 || |
|
120 |
- f->NumBindPairs != 3 || |
|
121 |
- f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 || |
|
122 |
- f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 || |
|
123 |
- f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2) |
|
124 |
- return SZ_ERROR_UNSUPPORTED; |
|
125 |
- return SZ_OK; |
|
126 |
- } |
|
127 |
- return SZ_ERROR_UNSUPPORTED; |
|
128 |
-} |
|
129 |
- |
|
130 |
-UInt64 GetSum(const UInt64 *values, UInt32 index) |
|
131 |
-{ |
|
132 |
- UInt64 sum = 0; |
|
133 |
- UInt32 i; |
|
134 |
- for (i = 0; i < index; i++) |
|
135 |
- sum += values[i]; |
|
136 |
- return sum; |
|
137 |
-} |
|
138 |
- |
|
139 |
-SRes SzDecode2(const UInt64 *packSizes, const CSzFolder *folder, |
|
140 |
- ILookInStream *inStream, UInt64 startPos, |
|
141 |
- Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain, |
|
142 |
- Byte *tempBuf[]) |
|
143 |
-{ |
|
144 |
- UInt32 ci; |
|
145 |
- SizeT tempSizes[3] = { 0, 0, 0}; |
|
146 |
- SizeT tempSize3 = 0; |
|
147 |
- Byte *tempBuf3 = 0; |
|
148 |
- |
|
149 |
- RINOK(CheckSupportedFolder(folder)); |
|
150 |
- |
|
151 |
- for (ci = 0; ci < folder->NumCoders; ci++) |
|
152 |
- { |
|
153 |
- CSzCoderInfo *coder = &folder->Coders[ci]; |
|
154 |
- |
|
155 |
- if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA) |
|
156 |
- { |
|
157 |
- UInt32 si = 0; |
|
158 |
- UInt64 offset; |
|
159 |
- UInt64 inSize; |
|
160 |
- Byte *outBufCur = outBuffer; |
|
161 |
- SizeT outSizeCur = outSize; |
|
162 |
- if (folder->NumCoders == 4) |
|
163 |
- { |
|
164 |
- UInt32 indices[] = { 3, 2, 0 }; |
|
165 |
- UInt64 unpackSize = folder->UnpackSizes[ci]; |
|
166 |
- si = indices[ci]; |
|
167 |
- if (ci < 2) |
|
168 |
- { |
|
169 |
- Byte *temp; |
|
170 |
- outSizeCur = (SizeT)unpackSize; |
|
171 |
- if (outSizeCur != unpackSize) |
|
172 |
- return SZ_ERROR_MEM; |
|
173 |
- if (outSizeCur) |
|
174 |
- temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur); |
|
175 |
- else |
|
176 |
- temp = 0; |
|
177 |
- if (temp == 0 && outSizeCur != 0) |
|
178 |
- return SZ_ERROR_MEM; |
|
179 |
- outBufCur = tempBuf[1 - ci] = temp; |
|
180 |
- tempSizes[1 - ci] = outSizeCur; |
|
181 |
- } |
|
182 |
- else if (ci == 2) |
|
183 |
- { |
|
184 |
- if (unpackSize > outSize) /* check it */ |
|
185 |
- return SZ_ERROR_PARAM; |
|
186 |
- tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize); |
|
187 |
- tempSize3 = outSizeCur = (SizeT)unpackSize; |
|
188 |
- } |
|
189 |
- else |
|
190 |
- return SZ_ERROR_UNSUPPORTED; |
|
191 |
- } |
|
192 |
- offset = GetSum(packSizes, si); |
|
193 |
- inSize = packSizes[si]; |
|
194 |
- RINOK(LookInStream_SeekTo(inStream, startPos + offset)); |
|
195 |
- |
|
196 |
- if (coder->MethodID == k_Copy) |
|
197 |
- { |
|
198 |
- if (inSize != outSizeCur) /* check it */ |
|
199 |
- return SZ_ERROR_DATA; |
|
200 |
- RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); |
|
201 |
- } |
|
202 |
- else |
|
203 |
- { |
|
204 |
- RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); |
|
205 |
- } |
|
206 |
- } |
|
207 |
- else if (coder->MethodID == k_BCJ) |
|
208 |
- { |
|
209 |
- UInt32 state; |
|
210 |
- if (ci != 1) |
|
211 |
- return SZ_ERROR_UNSUPPORTED; |
|
212 |
- x86_Convert_Init(state); |
|
213 |
- x86_Convert(outBuffer, outSize, 0, &state, 0); |
|
214 |
- } |
|
215 |
- else if (coder->MethodID == k_BCJ2) |
|
216 |
- { |
|
217 |
- UInt64 offset = GetSum(packSizes, 1); |
|
218 |
- UInt64 s3Size = packSizes[1]; |
|
219 |
- SRes res; |
|
220 |
- if (ci != 3) |
|
221 |
- return SZ_ERROR_UNSUPPORTED; |
|
222 |
- RINOK(LookInStream_SeekTo(inStream, startPos + offset)); |
|
223 |
- tempSizes[2] = (SizeT)s3Size; |
|
224 |
- if (tempSizes[2] != s3Size) |
|
225 |
- return SZ_ERROR_MEM; |
|
226 |
- tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]); |
|
227 |
- if (tempBuf[2] == 0 && tempSizes[2] != 0) |
|
228 |
- return SZ_ERROR_MEM; |
|
229 |
- res = SzDecodeCopy(s3Size, inStream, tempBuf[2]); |
|
230 |
- RINOK(res) |
|
231 |
- |
|
232 |
- res = Bcj2_Decode( |
|
233 |
- tempBuf3, tempSize3, |
|
234 |
- tempBuf[0], tempSizes[0], |
|
235 |
- tempBuf[1], tempSizes[1], |
|
236 |
- tempBuf[2], tempSizes[2], |
|
237 |
- outBuffer, outSize); |
|
238 |
- RINOK(res) |
|
239 |
- } |
|
240 |
- else |
|
241 |
- return SZ_ERROR_UNSUPPORTED; |
|
242 |
- } |
|
243 |
- return SZ_OK; |
|
244 |
-} |
|
245 |
- |
|
246 |
-SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder, |
|
247 |
- ILookInStream *inStream, UInt64 startPos, |
|
248 |
- Byte *outBuffer, size_t outSize, ISzAlloc *allocMain) |
|
249 |
-{ |
|
250 |
- Byte *tempBuf[3] = { 0, 0, 0}; |
|
251 |
- int i; |
|
252 |
- SRes res = SzDecode2(packSizes, folder, inStream, startPos, |
|
253 |
- outBuffer, (SizeT)outSize, allocMain, tempBuf); |
|
254 |
- for (i = 0; i < 3; i++) |
|
255 |
- IAlloc_Free(allocMain, tempBuf[i]); |
|
256 |
- return res; |
|
257 |
-} |
258 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,13 +0,0 @@ |
1 |
-/* 7zDecode.h -- Decoding from 7z folder |
|
2 |
-2008-11-23 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#ifndef __7Z_DECODE_H |
|
5 |
-#define __7Z_DECODE_H |
|
6 |
- |
|
7 |
-#include "7zItem.h" |
|
8 |
- |
|
9 |
-SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder, |
|
10 |
- ILookInStream *stream, UInt64 startPos, |
|
11 |
- Byte *outBuffer, size_t outSize, ISzAlloc *allocMain); |
|
12 |
- |
|
13 |
-#endif |
14 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,93 +0,0 @@ |
1 |
-/* 7zExtract.c -- Extracting from 7z archive |
|
2 |
-2008-11-23 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#include "../../7zCrc.h" |
|
5 |
-#include "7zDecode.h" |
|
6 |
-#include "7zExtract.h" |
|
7 |
- |
|
8 |
-SRes SzAr_Extract( |
|
9 |
- const CSzArEx *p, |
|
10 |
- ILookInStream *inStream, |
|
11 |
- UInt32 fileIndex, |
|
12 |
- UInt32 *blockIndex, |
|
13 |
- Byte **outBuffer, |
|
14 |
- size_t *outBufferSize, |
|
15 |
- size_t *offset, |
|
16 |
- size_t *outSizeProcessed, |
|
17 |
- ISzAlloc *allocMain, |
|
18 |
- ISzAlloc *allocTemp) |
|
19 |
-{ |
|
20 |
- UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex]; |
|
21 |
- SRes res = SZ_OK; |
|
22 |
- *offset = 0; |
|
23 |
- *outSizeProcessed = 0; |
|
24 |
- if (folderIndex == (UInt32)-1) |
|
25 |
- { |
|
26 |
- IAlloc_Free(allocMain, *outBuffer); |
|
27 |
- *blockIndex = folderIndex; |
|
28 |
- *outBuffer = 0; |
|
29 |
- *outBufferSize = 0; |
|
30 |
- return SZ_OK; |
|
31 |
- } |
|
32 |
- |
|
33 |
- if (*outBuffer == 0 || *blockIndex != folderIndex) |
|
34 |
- { |
|
35 |
- CSzFolder *folder = p->db.Folders + folderIndex; |
|
36 |
- UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder); |
|
37 |
- size_t unpackSize = (size_t)unpackSizeSpec; |
|
38 |
- UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0); |
|
39 |
- |
|
40 |
- if (unpackSize != unpackSizeSpec) |
|
41 |
- return SZ_ERROR_MEM; |
|
42 |
- *blockIndex = folderIndex; |
|
43 |
- IAlloc_Free(allocMain, *outBuffer); |
|
44 |
- *outBuffer = 0; |
|
45 |
- |
|
46 |
- RINOK(LookInStream_SeekTo(inStream, startOffset)); |
|
47 |
- |
|
48 |
- if (res == SZ_OK) |
|
49 |
- { |
|
50 |
- *outBufferSize = unpackSize; |
|
51 |
- if (unpackSize != 0) |
|
52 |
- { |
|
53 |
- *outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize); |
|
54 |
- if (*outBuffer == 0) |
|
55 |
- res = SZ_ERROR_MEM; |
|
56 |
- } |
|
57 |
- if (res == SZ_OK) |
|
58 |
- { |
|
59 |
- res = SzDecode(p->db.PackSizes + |
|
60 |
- p->FolderStartPackStreamIndex[folderIndex], folder, |
|
61 |
- inStream, startOffset, |
|
62 |
- *outBuffer, unpackSize, allocTemp); |
|
63 |
- if (res == SZ_OK) |
|
64 |
- { |
|
65 |
- if (folder->UnpackCRCDefined) |
|
66 |
- { |
|
67 |
- if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC) |
|
68 |
- res = SZ_ERROR_CRC; |
|
69 |
- } |
|
70 |
- } |
|
71 |
- } |
|
72 |
- } |
|
73 |
- } |
|
74 |
- if (res == SZ_OK) |
|
75 |
- { |
|
76 |
- UInt32 i; |
|
77 |
- CSzFileItem *fileItem = p->db.Files + fileIndex; |
|
78 |
- *offset = 0; |
|
79 |
- for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++) |
|
80 |
- *offset += (UInt32)p->db.Files[i].Size; |
|
81 |
- *outSizeProcessed = (size_t)fileItem->Size; |
|
82 |
- if (*offset + *outSizeProcessed > *outBufferSize) |
|
83 |
- return SZ_ERROR_FAIL; |
|
84 |
- { |
|
85 |
- if (fileItem->FileCRCDefined) |
|
86 |
- { |
|
87 |
- if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC) |
|
88 |
- res = SZ_ERROR_CRC; |
|
89 |
- } |
|
90 |
- } |
|
91 |
- } |
|
92 |
- return res; |
|
93 |
-} |
94 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,41 +0,0 @@ |
1 |
-/* 7zExtract.h -- Extracting from 7z archive |
|
2 |
-2008-11-23 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#ifndef __7Z_EXTRACT_H |
|
5 |
-#define __7Z_EXTRACT_H |
|
6 |
- |
|
7 |
-#include "7zIn.h" |
|
8 |
- |
|
9 |
-/* |
|
10 |
- SzExtract extracts file from archive |
|
11 |
- |
|
12 |
- *outBuffer must be 0 before first call for each new archive. |
|
13 |
- |
|
14 |
- Extracting cache: |
|
15 |
- If you need to decompress more than one file, you can send |
|
16 |
- these values from previous call: |
|
17 |
- *blockIndex, |
|
18 |
- *outBuffer, |
|
19 |
- *outBufferSize |
|
20 |
- You can consider "*outBuffer" as cache of solid block. If your archive is solid, |
|
21 |
- it will increase decompression speed. |
|
22 |
- |
|
23 |
- If you use external function, you can declare these 3 cache variables |
|
24 |
- (blockIndex, outBuffer, outBufferSize) as static in that external function. |
|
25 |
- |
|
26 |
- Free *outBuffer and set *outBuffer to 0, if you want to flush cache. |
|
27 |
-*/ |
|
28 |
- |
|
29 |
-SRes SzAr_Extract( |
|
30 |
- const CSzArEx *db, |
|
31 |
- ILookInStream *inStream, |
|
32 |
- UInt32 fileIndex, /* index of file */ |
|
33 |
- UInt32 *blockIndex, /* index of solid block */ |
|
34 |
- Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ |
|
35 |
- size_t *outBufferSize, /* buffer size for output buffer */ |
|
36 |
- size_t *offset, /* offset of stream for required file in *outBuffer */ |
|
37 |
- size_t *outSizeProcessed, /* size of file in *outBuffer */ |
|
38 |
- ISzAlloc *allocMain, |
|
39 |
- ISzAlloc *allocTemp); |
|
40 |
- |
|
41 |
-#endif |
7 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,57 +0,0 @@ |
1 |
-/* 7zHeader.h -- 7z Headers |
|
2 |
-2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#ifndef __7Z_HEADER_H |
|
5 |
-#define __7Z_HEADER_H |
|
6 |
- |
|
7 |
-#include "../../Types.h" |
|
8 |
- |
|
9 |
-#define k7zSignatureSize 6 |
|
10 |
-extern Byte k7zSignature[k7zSignatureSize]; |
|
11 |
- |
|
12 |
-#define k7zMajorVersion 0 |
|
13 |
- |
|
14 |
-#define k7zStartHeaderSize 0x20 |
|
15 |
- |
|
16 |
-enum EIdEnum |
|
17 |
-{ |
|
18 |
- k7zIdEnd, |
|
19 |
- |
|
20 |
- k7zIdHeader, |
|
21 |
- |
|
22 |
- k7zIdArchiveProperties, |
|
23 |
- |
|
24 |
- k7zIdAdditionalStreamsInfo, |
|
25 |
- k7zIdMainStreamsInfo, |
|
26 |
- k7zIdFilesInfo, |
|
27 |
- |
|
28 |
- k7zIdPackInfo, |
|
29 |
- k7zIdUnpackInfo, |
|
30 |
- k7zIdSubStreamsInfo, |
|
31 |
- |
|
32 |
- k7zIdSize, |
|
33 |
- k7zIdCRC, |
|
34 |
- |
|
35 |
- k7zIdFolder, |
|
36 |
- |
|
37 |
- k7zIdCodersUnpackSize, |
|
38 |
- k7zIdNumUnpackStream, |
|
39 |
- |
|
40 |
- k7zIdEmptyStream, |
|
41 |
- k7zIdEmptyFile, |
|
42 |
- k7zIdAnti, |
|
43 |
- |
|
44 |
- k7zIdName, |
|
45 |
- k7zIdCTime, |
|
46 |
- k7zIdATime, |
|
47 |
- k7zIdMTime, |
|
48 |
- k7zIdWinAttributes, |
|
49 |
- k7zIdComment, |
|
50 |
- |
|
51 |
- k7zIdEncodedHeader, |
|
52 |
- |
|
53 |
- k7zIdStartPos, |
|
54 |
- k7zIdDummy |
|
55 |
-}; |
|
56 |
- |
|
57 |
-#endif |
58 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,1229 +0,0 @@ |
1 |
-/* 7zIn.c -- 7z Input functions |
|
2 |
-2008-12-31 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#include "../../7zCrc.h" |
|
5 |
-#include "../../CpuArch.h" |
|
6 |
- |
|
7 |
-#include "7zDecode.h" |
|
8 |
-#include "7zIn.h" |
|
9 |
- |
|
10 |
-#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; } |
|
11 |
- |
|
12 |
-#define NUM_FOLDER_CODERS_MAX 32 |
|
13 |
-#define NUM_CODER_STREAMS_MAX 32 |
|
14 |
- |
|
15 |
-void SzArEx_Init(CSzArEx *p) |
|
16 |
-{ |
|
17 |
- SzAr_Init(&p->db); |
|
18 |
- p->FolderStartPackStreamIndex = 0; |
|
19 |
- p->PackStreamStartPositions = 0; |
|
20 |
- p->FolderStartFileIndex = 0; |
|
21 |
- p->FileIndexToFolderIndexMap = 0; |
|
22 |
-} |
|
23 |
- |
|
24 |
-void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc) |
|
25 |
-{ |
|
26 |
- IAlloc_Free(alloc, p->FolderStartPackStreamIndex); |
|
27 |
- IAlloc_Free(alloc, p->PackStreamStartPositions); |
|
28 |
- IAlloc_Free(alloc, p->FolderStartFileIndex); |
|
29 |
- IAlloc_Free(alloc, p->FileIndexToFolderIndexMap); |
|
30 |
- SzAr_Free(&p->db, alloc); |
|
31 |
- SzArEx_Init(p); |
|
32 |
-} |
|
33 |
- |
|
34 |
-/* |
|
35 |
-UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const |
|
36 |
-{ |
|
37 |
- return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex]; |
|
38 |
-} |
|
39 |
- |
|
40 |
-UInt64 GetFilePackSize(int fileIndex) const |
|
41 |
-{ |
|
42 |
- int folderIndex = FileIndexToFolderIndexMap[fileIndex]; |
|
43 |
- if (folderIndex >= 0) |
|
44 |
- { |
|
45 |
- const CSzFolder &folderInfo = Folders[folderIndex]; |
|
46 |
- if (FolderStartFileIndex[folderIndex] == fileIndex) |
|
47 |
- return GetFolderFullPackSize(folderIndex); |
|
48 |
- } |
|
49 |
- return 0; |
|
50 |
-} |
|
51 |
-*/ |
|
52 |
- |
|
53 |
-#define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \ |
|
54 |
- if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; } |
|
55 |
- |
|
56 |
-static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc) |
|
57 |
-{ |
|
58 |
- UInt32 startPos = 0; |
|
59 |
- UInt64 startPosSize = 0; |
|
60 |
- UInt32 i; |
|
61 |
- UInt32 folderIndex = 0; |
|
62 |
- UInt32 indexInFolder = 0; |
|
63 |
- MY_ALLOC(UInt32, p->FolderStartPackStreamIndex, p->db.NumFolders, alloc); |
|
64 |
- for (i = 0; i < p->db.NumFolders; i++) |
|
65 |
- { |
|
66 |
- p->FolderStartPackStreamIndex[i] = startPos; |
|
67 |
- startPos += p->db.Folders[i].NumPackStreams; |
|
68 |
- } |
|
69 |
- |
|
70 |
- MY_ALLOC(UInt64, p->PackStreamStartPositions, p->db.NumPackStreams, alloc); |
|
71 |
- |
|
72 |
- for (i = 0; i < p->db.NumPackStreams; i++) |
|
73 |
- { |
|
74 |
- p->PackStreamStartPositions[i] = startPosSize; |
|
75 |
- startPosSize += p->db.PackSizes[i]; |
|
76 |
- } |
|
77 |
- |
|
78 |
- MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders, alloc); |
|
79 |
- MY_ALLOC(UInt32, p->FileIndexToFolderIndexMap, p->db.NumFiles, alloc); |
|
80 |
- |
|
81 |
- for (i = 0; i < p->db.NumFiles; i++) |
|
82 |
- { |
|
83 |
- CSzFileItem *file = p->db.Files + i; |
|
84 |
- int emptyStream = !file->HasStream; |
|
85 |
- if (emptyStream && indexInFolder == 0) |
|
86 |
- { |
|
87 |
- p->FileIndexToFolderIndexMap[i] = (UInt32)-1; |
|
88 |
- continue; |
|
89 |
- } |
|
90 |
- if (indexInFolder == 0) |
|
91 |
- { |
|
92 |
- /* |
|
93 |
- v3.13 incorrectly worked with empty folders |
|
94 |
- v4.07: Loop for skipping empty folders |
|
95 |
- */ |
|
96 |
- for (;;) |
|
97 |
- { |
|
98 |
- if (folderIndex >= p->db.NumFolders) |
|
99 |
- return SZ_ERROR_ARCHIVE; |
|
100 |
- p->FolderStartFileIndex[folderIndex] = i; |
|
101 |
- if (p->db.Folders[folderIndex].NumUnpackStreams != 0) |
|
102 |
- break; |
|
103 |
- folderIndex++; |
|
104 |
- } |
|
105 |
- } |
|
106 |
- p->FileIndexToFolderIndexMap[i] = folderIndex; |
|
107 |
- if (emptyStream) |
|
108 |
- continue; |
|
109 |
- indexInFolder++; |
|
110 |
- if (indexInFolder >= p->db.Folders[folderIndex].NumUnpackStreams) |
|
111 |
- { |
|
112 |
- folderIndex++; |
|
113 |
- indexInFolder = 0; |
|
114 |
- } |
|
115 |
- } |
|
116 |
- return SZ_OK; |
|
117 |
-} |
|
118 |
- |
|
119 |
- |
|
120 |
-UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder) |
|
121 |
-{ |
|
122 |
- return p->dataPos + |
|
123 |
- p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder]; |
|
124 |
-} |
|
125 |
- |
|
126 |
-int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize) |
|
127 |
-{ |
|
128 |
- UInt32 packStreamIndex = p->FolderStartPackStreamIndex[folderIndex]; |
|
129 |
- CSzFolder *folder = p->db.Folders + folderIndex; |
|
130 |
- UInt64 size = 0; |
|
131 |
- UInt32 i; |
|
132 |
- for (i = 0; i < folder->NumPackStreams; i++) |
|
133 |
- { |
|
134 |
- UInt64 t = size + p->db.PackSizes[packStreamIndex + i]; |
|
135 |
- if (t < size) /* check it */ |
|
136 |
- return SZ_ERROR_FAIL; |
|
137 |
- size = t; |
|
138 |
- } |
|
139 |
- *resSize = size; |
|
140 |
- return SZ_OK; |
|
141 |
-} |
|
142 |
- |
|
143 |
- |
|
144 |
-/* |
|
145 |
-SRes SzReadTime(const CObjectVector<CBuf> &dataVector, |
|
146 |
- CObjectVector<CSzFileItem> &files, UInt64 type) |
|
147 |
-{ |
|
148 |
- CBoolVector boolVector; |
|
149 |
- RINOK(ReadBoolVector2(files.Size(), boolVector)) |
|
150 |
- |
|
151 |
- CStreamSwitch streamSwitch; |
|
152 |
- RINOK(streamSwitch.Set(this, &dataVector)); |
|
153 |
- |
|
154 |
- for (int i = 0; i < files.Size(); i++) |
|
155 |
- { |
|
156 |
- CSzFileItem &file = files[i]; |
|
157 |
- CArchiveFileTime fileTime; |
|
158 |
- bool defined = boolVector[i]; |
|
159 |
- if (defined) |
|
160 |
- { |
|
161 |
- UInt32 low, high; |
|
162 |
- RINOK(SzReadUInt32(low)); |
|
163 |
- RINOK(SzReadUInt32(high)); |
|
164 |
- fileTime.dwLowDateTime = low; |
|
165 |
- fileTime.dwHighDateTime = high; |
|
166 |
- } |
|
167 |
- switch(type) |
|
168 |
- { |
|
169 |
- case k7zIdCTime: file.IsCTimeDefined = defined; if (defined) file.CTime = fileTime; break; |
|
170 |
- case k7zIdATime: file.IsATimeDefined = defined; if (defined) file.ATime = fileTime; break; |
|
171 |
- case k7zIdMTime: file.IsMTimeDefined = defined; if (defined) file.MTime = fileTime; break; |
|
172 |
- } |
|
173 |
- } |
|
174 |
- return SZ_OK; |
|
175 |
-} |
|
176 |
-*/ |
|
177 |
- |
|
178 |
-static int TestSignatureCandidate(Byte *testBytes) |
|
179 |
-{ |
|
180 |
- size_t i; |
|
181 |
- for (i = 0; i < k7zSignatureSize; i++) |
|
182 |
- if (testBytes[i] != k7zSignature[i]) |
|
183 |
- return 0; |
|
184 |
- return 1; |
|
185 |
-} |
|
186 |
- |
|
187 |
-typedef struct _CSzState |
|
188 |
-{ |
|
189 |
- Byte *Data; |
|
190 |
- size_t Size; |
|
191 |
-}CSzData; |
|
192 |
- |
|
193 |
-static SRes SzReadByte(CSzData *sd, Byte *b) |
|
194 |
-{ |
|
195 |
- if (sd->Size == 0) |
|
196 |
- return SZ_ERROR_ARCHIVE; |
|
197 |
- sd->Size--; |
|
198 |
- *b = *sd->Data++; |
|
199 |
- return SZ_OK; |
|
200 |
-} |
|
201 |
- |
|
202 |
-static SRes SzReadBytes(CSzData *sd, Byte *data, size_t size) |
|
203 |
-{ |
|
204 |
- size_t i; |
|
205 |
- for (i = 0; i < size; i++) |
|
206 |
- { |
|
207 |
- RINOK(SzReadByte(sd, data + i)); |
|
208 |
- } |
|
209 |
- return SZ_OK; |
|
210 |
-} |
|
211 |
- |
|
212 |
-static SRes SzReadUInt32(CSzData *sd, UInt32 *value) |
|
213 |
-{ |
|
214 |
- int i; |
|
215 |
- *value = 0; |
|
216 |
- for (i = 0; i < 4; i++) |
|
217 |
- { |
|
218 |
- Byte b; |
|
219 |
- RINOK(SzReadByte(sd, &b)); |
|
220 |
- *value |= ((UInt32)(b) << (8 * i)); |
|
221 |
- } |
|
222 |
- return SZ_OK; |
|
223 |
-} |
|
224 |
- |
|
225 |
-static SRes SzReadNumber(CSzData *sd, UInt64 *value) |
|
226 |
-{ |
|
227 |
- Byte firstByte; |
|
228 |
- Byte mask = 0x80; |
|
229 |
- int i; |
|
230 |
- RINOK(SzReadByte(sd, &firstByte)); |
|
231 |
- *value = 0; |
|
232 |
- for (i = 0; i < 8; i++) |
|
233 |
- { |
|
234 |
- Byte b; |
|
235 |
- if ((firstByte & mask) == 0) |
|
236 |
- { |
|
237 |
- UInt64 highPart = firstByte & (mask - 1); |
|
238 |
- *value += (highPart << (8 * i)); |
|
239 |
- return SZ_OK; |
|
240 |
- } |
|
241 |
- RINOK(SzReadByte(sd, &b)); |
|
242 |
- *value |= ((UInt64)b << (8 * i)); |
|
243 |
- mask >>= 1; |
|
244 |
- } |
|
245 |
- return SZ_OK; |
|
246 |
-} |
|
247 |
- |
|
248 |
-static SRes SzReadNumber32(CSzData *sd, UInt32 *value) |
|
249 |
-{ |
|
250 |
- UInt64 value64; |
|
251 |
- RINOK(SzReadNumber(sd, &value64)); |
|
252 |
- if (value64 >= 0x80000000) |
|
253 |
- return SZ_ERROR_UNSUPPORTED; |
|
254 |
- if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2))) |
|
255 |
- return SZ_ERROR_UNSUPPORTED; |
|
256 |
- *value = (UInt32)value64; |
|
257 |
- return SZ_OK; |
|
258 |
-} |
|
259 |
- |
|
260 |
-static SRes SzReadID(CSzData *sd, UInt64 *value) |
|
261 |
-{ |
|
262 |
- return SzReadNumber(sd, value); |
|
263 |
-} |
|
264 |
- |
|
265 |
-static SRes SzSkeepDataSize(CSzData *sd, UInt64 size) |
|
266 |
-{ |
|
267 |
- if (size > sd->Size) |
|
268 |
- return SZ_ERROR_ARCHIVE; |
|
269 |
- sd->Size -= (size_t)size; |
|
270 |
- sd->Data += (size_t)size; |
|
271 |
- return SZ_OK; |
|
272 |
-} |
|
273 |
- |
|
274 |
-static SRes SzSkeepData(CSzData *sd) |
|
275 |
-{ |
|
276 |
- UInt64 size; |
|
277 |
- RINOK(SzReadNumber(sd, &size)); |
|
278 |
- return SzSkeepDataSize(sd, size); |
|
279 |
-} |
|
280 |
- |
|
281 |
-static SRes SzReadArchiveProperties(CSzData *sd) |
|
282 |
-{ |
|
283 |
- for (;;) |
|
284 |
- { |
|
285 |
- UInt64 type; |
|
286 |
- RINOK(SzReadID(sd, &type)); |
|
287 |
- if (type == k7zIdEnd) |
|
288 |
- break; |
|
289 |
- SzSkeepData(sd); |
|
290 |
- } |
|
291 |
- return SZ_OK; |
|
292 |
-} |
|
293 |
- |
|
294 |
-static SRes SzWaitAttribute(CSzData *sd, UInt64 attribute) |
|
295 |
-{ |
|
296 |
- for (;;) |
|
297 |
- { |
|
298 |
- UInt64 type; |
|
299 |
- RINOK(SzReadID(sd, &type)); |
|
300 |
- if (type == attribute) |
|
301 |
- return SZ_OK; |
|
302 |
- if (type == k7zIdEnd) |
|
303 |
- return SZ_ERROR_ARCHIVE; |
|
304 |
- RINOK(SzSkeepData(sd)); |
|
305 |
- } |
|
306 |
-} |
|
307 |
- |
|
308 |
-static SRes SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc) |
|
309 |
-{ |
|
310 |
- Byte b = 0; |
|
311 |
- Byte mask = 0; |
|
312 |
- size_t i; |
|
313 |
- MY_ALLOC(Byte, *v, numItems, alloc); |
|
314 |
- for (i = 0; i < numItems; i++) |
|
315 |
- { |
|
316 |
- if (mask == 0) |
|
317 |
- { |
|
318 |
- RINOK(SzReadByte(sd, &b)); |
|
319 |
- mask = 0x80; |
|
320 |
- } |
|
321 |
- (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0); |
|
322 |
- mask >>= 1; |
|
323 |
- } |
|
324 |
- return SZ_OK; |
|
325 |
-} |
|
326 |
- |
|
327 |
-static SRes SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc) |
|
328 |
-{ |
|
329 |
- Byte allAreDefined; |
|
330 |
- size_t i; |
|
331 |
- RINOK(SzReadByte(sd, &allAreDefined)); |
|
332 |
- if (allAreDefined == 0) |
|
333 |
- return SzReadBoolVector(sd, numItems, v, alloc); |
|
334 |
- MY_ALLOC(Byte, *v, numItems, alloc); |
|
335 |
- for (i = 0; i < numItems; i++) |
|
336 |
- (*v)[i] = 1; |
|
337 |
- return SZ_OK; |
|
338 |
-} |
|
339 |
- |
|
340 |
-static SRes SzReadHashDigests( |
|
341 |
- CSzData *sd, |
|
342 |
- size_t numItems, |
|
343 |
- Byte **digestsDefined, |
|
344 |
- UInt32 **digests, |
|
345 |
- ISzAlloc *alloc) |
|
346 |
-{ |
|
347 |
- size_t i; |
|
348 |
- RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, alloc)); |
|
349 |
- MY_ALLOC(UInt32, *digests, numItems, alloc); |
|
350 |
- for (i = 0; i < numItems; i++) |
|
351 |
- if ((*digestsDefined)[i]) |
|
352 |
- { |
|
353 |
- RINOK(SzReadUInt32(sd, (*digests) + i)); |
|
354 |
- } |
|
355 |
- return SZ_OK; |
|
356 |
-} |
|
357 |
- |
|
358 |
-static SRes SzReadPackInfo( |
|
359 |
- CSzData *sd, |
|
360 |
- UInt64 *dataOffset, |
|
361 |
- UInt32 *numPackStreams, |
|
362 |
- UInt64 **packSizes, |
|
363 |
- Byte **packCRCsDefined, |
|
364 |
- UInt32 **packCRCs, |
|
365 |
- ISzAlloc *alloc) |
|
366 |
-{ |
|
367 |
- UInt32 i; |
|
368 |
- RINOK(SzReadNumber(sd, dataOffset)); |
|
369 |
- RINOK(SzReadNumber32(sd, numPackStreams)); |
|
370 |
- |
|
371 |
- RINOK(SzWaitAttribute(sd, k7zIdSize)); |
|
372 |
- |
|
373 |
- MY_ALLOC(UInt64, *packSizes, (size_t)*numPackStreams, alloc); |
|
374 |
- |
|
375 |
- for (i = 0; i < *numPackStreams; i++) |
|
376 |
- { |
|
377 |
- RINOK(SzReadNumber(sd, (*packSizes) + i)); |
|
378 |
- } |
|
379 |
- |
|
380 |
- for (;;) |
|
381 |
- { |
|
382 |
- UInt64 type; |
|
383 |
- RINOK(SzReadID(sd, &type)); |
|
384 |
- if (type == k7zIdEnd) |
|
385 |
- break; |
|
386 |
- if (type == k7zIdCRC) |
|
387 |
- { |
|
388 |
- RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc)); |
|
389 |
- continue; |
|
390 |
- } |
|
391 |
- RINOK(SzSkeepData(sd)); |
|
392 |
- } |
|
393 |
- if (*packCRCsDefined == 0) |
|
394 |
- { |
|
395 |
- MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, alloc); |
|
396 |
- MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, alloc); |
|
397 |
- for (i = 0; i < *numPackStreams; i++) |
|
398 |
- { |
|
399 |
- (*packCRCsDefined)[i] = 0; |
|
400 |
- (*packCRCs)[i] = 0; |
|
401 |
- } |
|
402 |
- } |
|
403 |
- return SZ_OK; |
|
404 |
-} |
|
405 |
- |
|
406 |
-static SRes SzReadSwitch(CSzData *sd) |
|
407 |
-{ |
|
408 |
- Byte external; |
|
409 |
- RINOK(SzReadByte(sd, &external)); |
|
410 |
- return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED; |
|
411 |
-} |
|
412 |
- |
|
413 |
-static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc) |
|
414 |
-{ |
|
415 |
- UInt32 numCoders, numBindPairs, numPackStreams, i; |
|
416 |
- UInt32 numInStreams = 0, numOutStreams = 0; |
|
417 |
- |
|
418 |
- RINOK(SzReadNumber32(sd, &numCoders)); |
|
419 |
- if (numCoders > NUM_FOLDER_CODERS_MAX) |
|
420 |
- return SZ_ERROR_UNSUPPORTED; |
|
421 |
- folder->NumCoders = numCoders; |
|
422 |
- |
|
423 |
- MY_ALLOC(CSzCoderInfo, folder->Coders, (size_t)numCoders, alloc); |
|
424 |
- |
|
425 |
- for (i = 0; i < numCoders; i++) |
|
426 |
- SzCoderInfo_Init(folder->Coders + i); |
|
427 |
- |
|
428 |
- for (i = 0; i < numCoders; i++) |
|
429 |
- { |
|
430 |
- Byte mainByte; |
|
431 |
- CSzCoderInfo *coder = folder->Coders + i; |
|
432 |
- { |
|
433 |
- unsigned idSize, j; |
|
434 |
- Byte longID[15]; |
|
435 |
- RINOK(SzReadByte(sd, &mainByte)); |
|
436 |
- idSize = (unsigned)(mainByte & 0xF); |
|
437 |
- RINOK(SzReadBytes(sd, longID, idSize)); |
|
438 |
- if (idSize > sizeof(coder->MethodID)) |
|
439 |
- return SZ_ERROR_UNSUPPORTED; |
|
440 |
- coder->MethodID = 0; |
|
441 |
- for (j = 0; j < idSize; j++) |
|
442 |
- coder->MethodID |= (UInt64)longID[idSize - 1 - j] << (8 * j); |
|
443 |
- |
|
444 |
- if ((mainByte & 0x10) != 0) |
|
445 |
- { |
|
446 |
- RINOK(SzReadNumber32(sd, &coder->NumInStreams)); |
|
447 |
- RINOK(SzReadNumber32(sd, &coder->NumOutStreams)); |
|
448 |
- if (coder->NumInStreams > NUM_CODER_STREAMS_MAX || |
|
449 |
- coder->NumOutStreams > NUM_CODER_STREAMS_MAX) |
|
450 |
- return SZ_ERROR_UNSUPPORTED; |
|
451 |
- } |
|
452 |
- else |
|
453 |
- { |
|
454 |
- coder->NumInStreams = 1; |
|
455 |
- coder->NumOutStreams = 1; |
|
456 |
- } |
|
457 |
- if ((mainByte & 0x20) != 0) |
|
458 |
- { |
|
459 |
- UInt64 propertiesSize = 0; |
|
460 |
- RINOK(SzReadNumber(sd, &propertiesSize)); |
|
461 |
- if (!Buf_Create(&coder->Props, (size_t)propertiesSize, alloc)) |
|
462 |
- return SZ_ERROR_MEM; |
|
463 |
- RINOK(SzReadBytes(sd, coder->Props.data, (size_t)propertiesSize)); |
|
464 |
- } |
|
465 |
- } |
|
466 |
- while ((mainByte & 0x80) != 0) |
|
467 |
- { |
|
468 |
- RINOK(SzReadByte(sd, &mainByte)); |
|
469 |
- RINOK(SzSkeepDataSize(sd, (mainByte & 0xF))); |
|
470 |
- if ((mainByte & 0x10) != 0) |
|
471 |
- { |
|
472 |
- UInt32 n; |
|
473 |
- RINOK(SzReadNumber32(sd, &n)); |
|
474 |
- RINOK(SzReadNumber32(sd, &n)); |
|
475 |
- } |
|
476 |
- if ((mainByte & 0x20) != 0) |
|
477 |
- { |
|
478 |
- UInt64 propertiesSize = 0; |
|
479 |
- RINOK(SzReadNumber(sd, &propertiesSize)); |
|
480 |
- RINOK(SzSkeepDataSize(sd, propertiesSize)); |
|
481 |
- } |
|
482 |
- } |
|
483 |
- numInStreams += coder->NumInStreams; |
|
484 |
- numOutStreams += coder->NumOutStreams; |
|
485 |
- } |
|
486 |
- |
|
487 |
- if (numOutStreams == 0) |
|
488 |
- return SZ_ERROR_UNSUPPORTED; |
|
489 |
- |
|
490 |
- folder->NumBindPairs = numBindPairs = numOutStreams - 1; |
|
491 |
- MY_ALLOC(CBindPair, folder->BindPairs, (size_t)numBindPairs, alloc); |
|
492 |
- |
|
493 |
- for (i = 0; i < numBindPairs; i++) |
|
494 |
- { |
|
495 |
- CBindPair *bp = folder->BindPairs + i; |
|
496 |
- RINOK(SzReadNumber32(sd, &bp->InIndex)); |
|
497 |
- RINOK(SzReadNumber32(sd, &bp->OutIndex)); |
|
498 |
- } |
|
499 |
- |
|
500 |
- if (numInStreams < numBindPairs) |
|
501 |
- return SZ_ERROR_UNSUPPORTED; |
|
502 |
- |
|
503 |
- folder->NumPackStreams = numPackStreams = numInStreams - numBindPairs; |
|
504 |
- MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackStreams, alloc); |
|
505 |
- |
|
506 |
- if (numPackStreams == 1) |
|
507 |
- { |
|
508 |
- for (i = 0; i < numInStreams ; i++) |
|
509 |
- if (SzFolder_FindBindPairForInStream(folder, i) < 0) |
|
510 |
- break; |
|
511 |
- if (i == numInStreams) |
|
512 |
- return SZ_ERROR_UNSUPPORTED; |
|
513 |
- folder->PackStreams[0] = i; |
|
514 |
- } |
|
515 |
- else |
|
516 |
- for (i = 0; i < numPackStreams; i++) |
|
517 |
- { |
|
518 |
- RINOK(SzReadNumber32(sd, folder->PackStreams + i)); |
|
519 |
- } |
|
520 |
- return SZ_OK; |
|
521 |
-} |
|
522 |
- |
|
523 |
-static SRes SzReadUnpackInfo( |
|
524 |
- CSzData *sd, |
|
525 |
- UInt32 *numFolders, |
|
526 |
- CSzFolder **folders, /* for alloc */ |
|
527 |
- ISzAlloc *alloc, |
|
528 |
- ISzAlloc *allocTemp) |
|
529 |
-{ |
|
530 |
- UInt32 i; |
|
531 |
- RINOK(SzWaitAttribute(sd, k7zIdFolder)); |
|
532 |
- RINOK(SzReadNumber32(sd, numFolders)); |
|
533 |
- { |
|
534 |
- RINOK(SzReadSwitch(sd)); |
|
535 |
- |
|
536 |
- MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc); |
|
537 |
- |
|
538 |
- for (i = 0; i < *numFolders; i++) |
|
539 |
- SzFolder_Init((*folders) + i); |
|
540 |
- |
|
541 |
- for (i = 0; i < *numFolders; i++) |
|
542 |
- { |
|
543 |
- RINOK(SzGetNextFolderItem(sd, (*folders) + i, alloc)); |
|
544 |
- } |
|
545 |
- } |
|
546 |
- |
|
547 |
- RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize)); |
|
548 |
- |
|
549 |
- for (i = 0; i < *numFolders; i++) |
|
550 |
- { |
|
551 |
- UInt32 j; |
|
552 |
- CSzFolder *folder = (*folders) + i; |
|
553 |
- UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder); |
|
554 |
- |
|
555 |
- MY_ALLOC(UInt64, folder->UnpackSizes, (size_t)numOutStreams, alloc); |
|
556 |
- |
|
557 |
- for (j = 0; j < numOutStreams; j++) |
|
558 |
- { |
|
559 |
- RINOK(SzReadNumber(sd, folder->UnpackSizes + j)); |
|
560 |
- } |
|
561 |
- } |
|
562 |
- |
|
563 |
- for (;;) |
|
564 |
- { |
|
565 |
- UInt64 type; |
|
566 |
- RINOK(SzReadID(sd, &type)); |
|
567 |
- if (type == k7zIdEnd) |
|
568 |
- return SZ_OK; |
|
569 |
- if (type == k7zIdCRC) |
|
570 |
- { |
|
571 |
- SRes res; |
|
572 |
- Byte *crcsDefined = 0; |
|
573 |
- UInt32 *crcs = 0; |
|
574 |
- res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp); |
|
575 |
- if (res == SZ_OK) |
|
576 |
- { |
|
577 |
- for (i = 0; i < *numFolders; i++) |
|
578 |
- { |
|
579 |
- CSzFolder *folder = (*folders) + i; |
|
580 |
- folder->UnpackCRCDefined = crcsDefined[i]; |
|
581 |
- folder->UnpackCRC = crcs[i]; |
|
582 |
- } |
|
583 |
- } |
|
584 |
- IAlloc_Free(allocTemp, crcs); |
|
585 |
- IAlloc_Free(allocTemp, crcsDefined); |
|
586 |
- RINOK(res); |
|
587 |
- continue; |
|
588 |
- } |
|
589 |
- RINOK(SzSkeepData(sd)); |
|
590 |
- } |
|
591 |
-} |
|
592 |
- |
|
593 |
-static SRes SzReadSubStreamsInfo( |
|
594 |
- CSzData *sd, |
|
595 |
- UInt32 numFolders, |
|
596 |
- CSzFolder *folders, |
|
597 |
- UInt32 *numUnpackStreams, |
|
598 |
- UInt64 **unpackSizes, |
|
599 |
- Byte **digestsDefined, |
|
600 |
- UInt32 **digests, |
|
601 |
- ISzAlloc *allocTemp) |
|
602 |
-{ |
|
603 |
- UInt64 type = 0; |
|
604 |
- UInt32 i; |
|
605 |
- UInt32 si = 0; |
|
606 |
- UInt32 numDigests = 0; |
|
607 |
- |
|
608 |
- for (i = 0; i < numFolders; i++) |
|
609 |
- folders[i].NumUnpackStreams = 1; |
|
610 |
- *numUnpackStreams = numFolders; |
|
611 |
- |
|
612 |
- for (;;) |
|
613 |
- { |
|
614 |
- RINOK(SzReadID(sd, &type)); |
|
615 |
- if (type == k7zIdNumUnpackStream) |
|
616 |
- { |
|
617 |
- *numUnpackStreams = 0; |
|
618 |
- for (i = 0; i < numFolders; i++) |
|
619 |
- { |
|
620 |
- UInt32 numStreams; |
|
621 |
- RINOK(SzReadNumber32(sd, &numStreams)); |
|
622 |
- folders[i].NumUnpackStreams = numStreams; |
|
623 |
- *numUnpackStreams += numStreams; |
|
624 |
- } |
|
625 |
- continue; |
|
626 |
- } |
|
627 |
- if (type == k7zIdCRC || type == k7zIdSize) |
|
628 |
- break; |
|
629 |
- if (type == k7zIdEnd) |
|
630 |
- break; |
|
631 |
- RINOK(SzSkeepData(sd)); |
|
632 |
- } |
|
633 |
- |
|
634 |
- if (*numUnpackStreams == 0) |
|
635 |
- { |
|
636 |
- *unpackSizes = 0; |
|
637 |
- *digestsDefined = 0; |
|
638 |
- *digests = 0; |
|
639 |
- } |
|
640 |
- else |
|
641 |
- { |
|
642 |
- *unpackSizes = (UInt64 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt64)); |
|
643 |
- RINOM(*unpackSizes); |
|
644 |
- *digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(Byte)); |
|
645 |
- RINOM(*digestsDefined); |
|
646 |
- *digests = (UInt32 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt32)); |
|
647 |
- RINOM(*digests); |
|
648 |
- } |
|
649 |
- |
|
650 |
- for (i = 0; i < numFolders && *unpackSizes; i++) |
|
651 |
- { |
|
652 |
- /* |
|
653 |
- v3.13 incorrectly worked with empty folders |
|
654 |
- v4.07: we check that folder is empty |
|
655 |
- */ |
|
656 |
- UInt64 sum = 0; |
|
657 |
- UInt32 j; |
|
658 |
- UInt32 numSubstreams = folders[i].NumUnpackStreams; |
|
659 |
- if (numSubstreams == 0) |
|
660 |
- continue; |
|
661 |
- if (type == k7zIdSize) |
|
662 |
- for (j = 1; j < numSubstreams; j++) |
|
663 |
- { |
|
664 |
- UInt64 size; |
|
665 |
- RINOK(SzReadNumber(sd, &size)); |
|
666 |
- (*unpackSizes)[si++] = size; |
|
667 |
- sum += size; |
|
668 |
- } |
|
669 |
- (*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum; |
|
670 |
- } |
|
671 |
- if (type == k7zIdSize) |
|
672 |
- { |
|
673 |
- RINOK(SzReadID(sd, &type)); |
|
674 |
- } |
|
675 |
- |
|
676 |
- for (i = 0; i < *numUnpackStreams; i++) |
|
677 |
- { |
|
678 |
- (*digestsDefined)[i] = 0; |
|
679 |
- (*digests)[i] = 0; |
|
680 |
- } |
|
681 |
- |
|
682 |
- |
|
683 |
- for (i = 0; i < numFolders; i++) |
|
684 |
- { |
|
685 |
- UInt32 numSubstreams = folders[i].NumUnpackStreams; |
|
686 |
- if (numSubstreams != 1 || !folders[i].UnpackCRCDefined) |
|
687 |
- numDigests += numSubstreams; |
|
688 |
- } |
|
689 |
- |
|
690 |
- |
|
691 |
- si = 0; |
|
692 |
- for (;;) |
|
693 |
- { |
|
694 |
- if (type == k7zIdCRC) |
|
695 |
- { |
|
696 |
- int digestIndex = 0; |
|
697 |
- Byte *digestsDefined2 = 0; |
|
698 |
- UInt32 *digests2 = 0; |
|
699 |
- SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp); |
|
700 |
- if (res == SZ_OK) |
|
701 |
- { |
|
702 |
- for (i = 0; i < numFolders; i++) |
|
703 |
- { |
|
704 |
- CSzFolder *folder = folders + i; |
|
705 |
- UInt32 numSubstreams = folder->NumUnpackStreams; |
|
706 |
- if (numSubstreams == 1 && folder->UnpackCRCDefined) |
|
707 |
- { |
|
708 |
- (*digestsDefined)[si] = 1; |
|
709 |
- (*digests)[si] = folder->UnpackCRC; |
|
710 |
- si++; |
|
711 |
- } |
|
712 |
- else |
|
713 |
- { |
|
714 |
- UInt32 j; |
|
715 |
- for (j = 0; j < numSubstreams; j++, digestIndex++) |
|
716 |
- { |
|
717 |
- (*digestsDefined)[si] = digestsDefined2[digestIndex]; |
|
718 |
- (*digests)[si] = digests2[digestIndex]; |
|
719 |
- si++; |
|
720 |
- } |
|
721 |
- } |
|
722 |
- } |
|
723 |
- } |
|
724 |
- IAlloc_Free(allocTemp, digestsDefined2); |
|
725 |
- IAlloc_Free(allocTemp, digests2); |
|
726 |
- RINOK(res); |
|
727 |
- } |
|
728 |
- else if (type == k7zIdEnd) |
|
729 |
- return SZ_OK; |
|
730 |
- else |
|
731 |
- { |
|
732 |
- RINOK(SzSkeepData(sd)); |
|
733 |
- } |
|
734 |
- RINOK(SzReadID(sd, &type)); |
|
735 |
- } |
|
736 |
-} |
|
737 |
- |
|
738 |
- |
|
739 |
-static SRes SzReadStreamsInfo( |
|
740 |
- CSzData *sd, |
|
741 |
- UInt64 *dataOffset, |
|
742 |
- CSzAr *p, |
|
743 |
- UInt32 *numUnpackStreams, |
|
744 |
- UInt64 **unpackSizes, /* allocTemp */ |
|
745 |
- Byte **digestsDefined, /* allocTemp */ |
|
746 |
- UInt32 **digests, /* allocTemp */ |
|
747 |
- ISzAlloc *alloc, |
|
748 |
- ISzAlloc *allocTemp) |
|
749 |
-{ |
|
750 |
- for (;;) |
|
751 |
- { |
|
752 |
- UInt64 type; |
|
753 |
- RINOK(SzReadID(sd, &type)); |
|
754 |
- if ((UInt64)(int)type != type) |
|
755 |
- return SZ_ERROR_UNSUPPORTED; |
|
756 |
- switch((int)type) |
|
757 |
- { |
|
758 |
- case k7zIdEnd: |
|
759 |
- return SZ_OK; |
|
760 |
- case k7zIdPackInfo: |
|
761 |
- { |
|
762 |
- RINOK(SzReadPackInfo(sd, dataOffset, &p->NumPackStreams, |
|
763 |
- &p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc)); |
|
764 |
- break; |
|
765 |
- } |
|
766 |
- case k7zIdUnpackInfo: |
|
767 |
- { |
|
768 |
- RINOK(SzReadUnpackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp)); |
|
769 |
- break; |
|
770 |
- } |
|
771 |
- case k7zIdSubStreamsInfo: |
|
772 |
- { |
|
773 |
- RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders, |
|
774 |
- numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp)); |
|
775 |
- break; |
|
776 |
- } |
|
777 |
- default: |
|
778 |
- return SZ_ERROR_UNSUPPORTED; |
|
779 |
- } |
|
780 |
- } |
|
781 |
-} |
|
782 |
- |
|
783 |
-Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; |
|
784 |
- |
|
785 |
-static SRes SzReadFileNames(CSzData *sd, UInt32 numFiles, CSzFileItem *files, ISzAlloc *alloc) |
|
786 |
-{ |
|
787 |
- UInt32 i; |
|
788 |
- for (i = 0; i < numFiles; i++) |
|
789 |
- { |
|
790 |
- UInt32 len = 0; |
|
791 |
- UInt32 pos = 0; |
|
792 |
- CSzFileItem *file = files + i; |
|
793 |
- while (pos + 2 <= sd->Size) |
|
794 |
- { |
|
795 |
- int numAdds; |
|
796 |
- UInt32 value = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8)); |
|
797 |
- pos += 2; |
|
798 |
- len++; |
|
799 |
- if (value == 0) |
|
800 |
- break; |
|
801 |
- if (value < 0x80) |
|
802 |
- continue; |
|
803 |
- if (value >= 0xD800 && value < 0xE000) |
|
804 |
- { |
|
805 |
- UInt32 c2; |
|
806 |
- if (value >= 0xDC00) |
|
807 |
- return SZ_ERROR_ARCHIVE; |
|
808 |
- if (pos + 2 > sd->Size) |
|
809 |
- return SZ_ERROR_ARCHIVE; |
|
810 |
- c2 = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8)); |
|
811 |
- pos += 2; |
|
812 |
- if (c2 < 0xDC00 || c2 >= 0xE000) |
|
813 |
- return SZ_ERROR_ARCHIVE; |
|
814 |
- value = ((value - 0xD800) << 10) | (c2 - 0xDC00); |
|
815 |
- } |
|
816 |
- for (numAdds = 1; numAdds < 5; numAdds++) |
|
817 |
- if (value < (((UInt32)1) << (numAdds * 5 + 6))) |
|
818 |
- break; |
|
819 |
- len += numAdds; |
|
820 |
- } |
|
821 |
- |
|
822 |
- MY_ALLOC(char, file->Name, (size_t)len, alloc); |
|
823 |
- |
|
824 |
- len = 0; |
|
825 |
- while (2 <= sd->Size) |
|
826 |
- { |
|
827 |
- int numAdds; |
|
828 |
- UInt32 value = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8)); |
|
829 |
- SzSkeepDataSize(sd, 2); |
|
830 |
- if (value < 0x80) |
|
831 |
- { |
|
832 |
- file->Name[len++] = (char)value; |
|
833 |
- if (value == 0) |
|
834 |
- break; |
|
835 |
- continue; |
|
836 |
- } |
|
837 |
- if (value >= 0xD800 && value < 0xE000) |
|
838 |
- { |
|
839 |
- UInt32 c2 = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8)); |
|
840 |
- SzSkeepDataSize(sd, 2); |
|
841 |
- value = ((value - 0xD800) << 10) | (c2 - 0xDC00); |
|
842 |
- } |
|
843 |
- for (numAdds = 1; numAdds < 5; numAdds++) |
|
844 |
- if (value < (((UInt32)1) << (numAdds * 5 + 6))) |
|
845 |
- break; |
|
846 |
- file->Name[len++] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds))); |
|
847 |
- do |
|
848 |
- { |
|
849 |
- numAdds--; |
|
850 |
- file->Name[len++] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F)); |
|
851 |
- } |
|
852 |
- while (numAdds > 0); |
|
853 |
- |
|
854 |
- len += numAdds; |
|
855 |
- } |
|
856 |
- } |
|
857 |
- return SZ_OK; |
|
858 |
-} |
|
859 |
- |
|
860 |
-static SRes SzReadHeader2( |
|
861 |
- CSzArEx *p, /* allocMain */ |
|
862 |
- CSzData *sd, |
|
863 |
- UInt64 **unpackSizes, /* allocTemp */ |
|
864 |
- Byte **digestsDefined, /* allocTemp */ |
|
865 |
- UInt32 **digests, /* allocTemp */ |
|
866 |
- Byte **emptyStreamVector, /* allocTemp */ |
|
867 |
- Byte **emptyFileVector, /* allocTemp */ |
|
868 |
- Byte **lwtVector, /* allocTemp */ |
|
869 |
- ISzAlloc *allocMain, |
|
870 |
- ISzAlloc *allocTemp) |
|
871 |
-{ |
|
872 |
- UInt64 type; |
|
873 |
- UInt32 numUnpackStreams = 0; |
|
874 |
- UInt32 numFiles = 0; |
|
875 |
- CSzFileItem *files = 0; |
|
876 |
- UInt32 numEmptyStreams = 0; |
|
877 |
- UInt32 i; |
|
878 |
- |
|
879 |
- RINOK(SzReadID(sd, &type)); |
|
880 |
- |
|
881 |
- if (type == k7zIdArchiveProperties) |
|
882 |
- { |
|
883 |
- RINOK(SzReadArchiveProperties(sd)); |
|
884 |
- RINOK(SzReadID(sd, &type)); |
|
885 |
- } |
|
886 |
- |
|
887 |
- |
|
888 |
- if (type == k7zIdMainStreamsInfo) |
|
889 |
- { |
|
890 |
- RINOK(SzReadStreamsInfo(sd, |
|
891 |
- &p->dataPos, |
|
892 |
- &p->db, |
|
893 |
- &numUnpackStreams, |
|
894 |
- unpackSizes, |
|
895 |
- digestsDefined, |
|
896 |
- digests, allocMain, allocTemp)); |
|
897 |
- p->dataPos += p->startPosAfterHeader; |
|
898 |
- RINOK(SzReadID(sd, &type)); |
|
899 |
- } |
|
900 |
- |
|
901 |
- if (type == k7zIdEnd) |
|
902 |
- return SZ_OK; |
|
903 |
- if (type != k7zIdFilesInfo) |
|
904 |
- return SZ_ERROR_ARCHIVE; |
|
905 |
- |
|
906 |
- RINOK(SzReadNumber32(sd, &numFiles)); |
|
907 |
- p->db.NumFiles = numFiles; |
|
908 |
- |
|
909 |
- MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain); |
|
910 |
- |
|
911 |
- p->db.Files = files; |
|
912 |
- for (i = 0; i < numFiles; i++) |
|
913 |
- SzFile_Init(files + i); |
|
914 |
- |
|
915 |
- for (;;) |
|
916 |
- { |
|
917 |
- UInt64 type; |
|
918 |
- UInt64 size; |
|
919 |
- RINOK(SzReadID(sd, &type)); |
|
920 |
- if (type == k7zIdEnd) |
|
921 |
- break; |
|
922 |
- RINOK(SzReadNumber(sd, &size)); |
|
923 |
- |
|
924 |
- if ((UInt64)(int)type != type) |
|
925 |
- { |
|
926 |
- RINOK(SzSkeepDataSize(sd, size)); |
|
927 |
- } |
|
928 |
- else |
|
929 |
- switch((int)type) |
|
930 |
- { |
|
931 |
- case k7zIdName: |
|
932 |
- { |
|
933 |
- RINOK(SzReadSwitch(sd)); |
|
934 |
- RINOK(SzReadFileNames(sd, numFiles, files, allocMain)) |
|
935 |
- break; |
|
936 |
- } |
|
937 |
- case k7zIdEmptyStream: |
|
938 |
- { |
|
939 |
- RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp)); |
|
940 |
- numEmptyStreams = 0; |
|
941 |
- for (i = 0; i < numFiles; i++) |
|
942 |
- if ((*emptyStreamVector)[i]) |
|
943 |
- numEmptyStreams++; |
|
944 |
- break; |
|
945 |
- } |
|
946 |
- case k7zIdEmptyFile: |
|
947 |
- { |
|
948 |
- RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp)); |
|
949 |
- break; |
|
950 |
- } |
|
951 |
- case k7zIdMTime: |
|
952 |
- { |
|
953 |
- RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp)); |
|
954 |
- RINOK(SzReadSwitch(sd)); |
|
955 |
- for (i = 0; i < numFiles; i++) |
|
956 |
- { |
|
957 |
- CSzFileItem *f = &files[i]; |
|
958 |
- Byte defined = (*lwtVector)[i]; |
|
959 |
- f->MTimeDefined = defined; |
|
960 |
- f->MTime.Low = f->MTime.High = 0; |
|
961 |
- if (defined) |
|
962 |
- { |
|
963 |
- RINOK(SzReadUInt32(sd, &f->MTime.Low)); |
|
964 |
- RINOK(SzReadUInt32(sd, &f->MTime.High)); |
|
965 |
- } |
|
966 |
- } |
|
967 |
- break; |
|
968 |
- } |
|
969 |
- default: |
|
970 |
- { |
|
971 |
- RINOK(SzSkeepDataSize(sd, size)); |
|
972 |
- } |
|
973 |
- } |
|
974 |
- } |
|
975 |
- |
|
976 |
- { |
|
977 |
- UInt32 emptyFileIndex = 0; |
|
978 |
- UInt32 sizeIndex = 0; |
|
979 |
- for (i = 0; i < numFiles; i++) |
|
980 |
- { |
|
981 |
- CSzFileItem *file = files + i; |
|
982 |
- file->IsAnti = 0; |
|
983 |
- if (*emptyStreamVector == 0) |
|
984 |
- file->HasStream = 1; |
|
985 |
- else |
|
986 |
- file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1); |
|
987 |
- if (file->HasStream) |
|
988 |
- { |
|
989 |
- file->IsDir = 0; |
|
990 |
- file->Size = (*unpackSizes)[sizeIndex]; |
|
991 |
- file->FileCRC = (*digests)[sizeIndex]; |
|
992 |
- file->FileCRCDefined = (Byte)(*digestsDefined)[sizeIndex]; |
|
993 |
- sizeIndex++; |
|
994 |
- } |
|
995 |
- else |
|
996 |
- { |
|
997 |
- if (*emptyFileVector == 0) |
|
998 |
- file->IsDir = 1; |
|
999 |
- else |
|
1000 |
- file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1); |
|
1001 |
- emptyFileIndex++; |
|
1002 |
- file->Size = 0; |
|
1003 |
- file->FileCRCDefined = 0; |
|
1004 |
- } |
|
1005 |
- } |
|
1006 |
- } |
|
1007 |
- return SzArEx_Fill(p, allocMain); |
|
1008 |
-} |
|
1009 |
- |
|
1010 |
-static SRes SzReadHeader( |
|
1011 |
- CSzArEx *p, |
|
1012 |
- CSzData *sd, |
|
1013 |
- ISzAlloc *allocMain, |
|
1014 |
- ISzAlloc *allocTemp) |
|
1015 |
-{ |
|
1016 |
- UInt64 *unpackSizes = 0; |
|
1017 |
- Byte *digestsDefined = 0; |
|
1018 |
- UInt32 *digests = 0; |
|
1019 |
- Byte *emptyStreamVector = 0; |
|
1020 |
- Byte *emptyFileVector = 0; |
|
1021 |
- Byte *lwtVector = 0; |
|
1022 |
- SRes res = SzReadHeader2(p, sd, |
|
1023 |
- &unpackSizes, &digestsDefined, &digests, |
|
1024 |
- &emptyStreamVector, &emptyFileVector, &lwtVector, |
|
1025 |
- allocMain, allocTemp); |
|
1026 |
- IAlloc_Free(allocTemp, unpackSizes); |
|
1027 |
- IAlloc_Free(allocTemp, digestsDefined); |
|
1028 |
- IAlloc_Free(allocTemp, digests); |
|
1029 |
- IAlloc_Free(allocTemp, emptyStreamVector); |
|
1030 |
- IAlloc_Free(allocTemp, emptyFileVector); |
|
1031 |
- IAlloc_Free(allocTemp, lwtVector); |
|
1032 |
- return res; |
|
1033 |
-} |
|
1034 |
- |
|
1035 |
-static SRes SzReadAndDecodePackedStreams2( |
|
1036 |
- ILookInStream *inStream, |
|
1037 |
- CSzData *sd, |
|
1038 |
- CBuf *outBuffer, |
|
1039 |
- UInt64 baseOffset, |
|
1040 |
- CSzAr *p, |
|
1041 |
- UInt64 **unpackSizes, |
|
1042 |
- Byte **digestsDefined, |
|
1043 |
- UInt32 **digests, |
|
1044 |
- ISzAlloc *allocTemp) |
|
1045 |
-{ |
|
1046 |
- |
|
1047 |
- UInt32 numUnpackStreams = 0; |
|
1048 |
- UInt64 dataStartPos; |
|
1049 |
- CSzFolder *folder; |
|
1050 |
- UInt64 unpackSize; |
|
1051 |
- SRes res; |
|
1052 |
- |
|
1053 |
- RINOK(SzReadStreamsInfo(sd, &dataStartPos, p, |
|
1054 |
- &numUnpackStreams, unpackSizes, digestsDefined, digests, |
|
1055 |
- allocTemp, allocTemp)); |
|
1056 |
- |
|
1057 |
- dataStartPos += baseOffset; |
|
1058 |
- if (p->NumFolders != 1) |
|
1059 |
- return SZ_ERROR_ARCHIVE; |
|
1060 |
- |
|
1061 |
- folder = p->Folders; |
|
1062 |
- unpackSize = SzFolder_GetUnpackSize(folder); |
|
1063 |
- |
|
1064 |
- RINOK(LookInStream_SeekTo(inStream, dataStartPos)); |
|
1065 |
- |
|
1066 |
- if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp)) |
|
1067 |
- return SZ_ERROR_MEM; |
|
1068 |
- |
|
1069 |
- res = SzDecode(p->PackSizes, folder, |
|
1070 |
- inStream, dataStartPos, |
|
1071 |
- outBuffer->data, (size_t)unpackSize, allocTemp); |
|
1072 |
- RINOK(res); |
|
1073 |
- if (folder->UnpackCRCDefined) |
|
1074 |
- if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC) |
|
1075 |
- return SZ_ERROR_CRC; |
|
1076 |
- return SZ_OK; |
|
1077 |
-} |
|
1078 |
- |
|
1079 |
-static SRes SzReadAndDecodePackedStreams( |
|
1080 |
- ILookInStream *inStream, |
|
1081 |
- CSzData *sd, |
|
1082 |
- CBuf *outBuffer, |
|
1083 |
- UInt64 baseOffset, |
|
1084 |
- ISzAlloc *allocTemp) |
|
1085 |
-{ |
|
1086 |
- CSzAr p; |
|
1087 |
- UInt64 *unpackSizes = 0; |
|
1088 |
- Byte *digestsDefined = 0; |
|
1089 |
- UInt32 *digests = 0; |
|
1090 |
- SRes res; |
|
1091 |
- SzAr_Init(&p); |
|
1092 |
- res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset, |
|
1093 |
- &p, &unpackSizes, &digestsDefined, &digests, |
|
1094 |
- allocTemp); |
|
1095 |
- SzAr_Free(&p, allocTemp); |
|
1096 |
- IAlloc_Free(allocTemp, unpackSizes); |
|
1097 |
- IAlloc_Free(allocTemp, digestsDefined); |
|
1098 |
- IAlloc_Free(allocTemp, digests); |
|
1099 |
- return res; |
|
1100 |
-} |
|
1101 |
- |
|
1102 |
-static SRes SzArEx_Open2( |
|
1103 |
- CSzArEx *p, |
|
1104 |
- ILookInStream *inStream, |
|
1105 |
- ISzAlloc *allocMain, |
|
1106 |
- ISzAlloc *allocTemp) |
|
1107 |
-{ |
|
1108 |
- Byte header[k7zStartHeaderSize]; |
|
1109 |
- UInt64 nextHeaderOffset, nextHeaderSize; |
|
1110 |
- size_t nextHeaderSizeT; |
|
1111 |
- UInt32 nextHeaderCRC; |
|
1112 |
- CBuf buffer; |
|
1113 |
- SRes res; |
|
1114 |
- |
|
1115 |
- RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE)); |
|
1116 |
- |
|
1117 |
- if (!TestSignatureCandidate(header)) |
|
1118 |
- return SZ_ERROR_NO_ARCHIVE; |
|
1119 |
- if (header[6] != k7zMajorVersion) |
|
1120 |
- return SZ_ERROR_UNSUPPORTED; |
|
1121 |
- |
|
1122 |
- nextHeaderOffset = GetUi64(header + 12); |
|
1123 |
- nextHeaderSize = GetUi64(header + 20); |
|
1124 |
- nextHeaderCRC = GetUi32(header + 28); |
|
1125 |
- |
|
1126 |
- p->startPosAfterHeader = k7zStartHeaderSize; |
|
1127 |
- |
|
1128 |
-/* aCaB - 2010-02-16 - RECOVERY MODE |
|
1129 |
- if (CrcCalc(header + 12, 20) != GetUi32(header + 8)) |
|
1130 |
- return SZ_ERROR_CRC; */ |
|
1131 |
- if(!GetUi32(header + 8) && !nextHeaderOffset && !nextHeaderSize && !nextHeaderCRC) { |
|
1132 |
- int i, checkSize = 500; |
|
1133 |
- Byte buf[500]; |
|
1134 |
- Int64 curpos=0, endpos=0, readpos; |
|
1135 |
- RINOK(inStream->Seek(inStream, &curpos, SZ_SEEK_CUR)); |
|
1136 |
- RINOK(inStream->Seek(inStream, &endpos, SZ_SEEK_END)); |
|
1137 |
- if(endpos-curpos < 500) checkSize = endpos-curpos; |
|
1138 |
- readpos = endpos - checkSize; |
|
1139 |
- RINOK(inStream->Seek(inStream, &readpos, SZ_SEEK_SET)); |
|
1140 |
- RINOK(LookInStream_Read2(inStream, buf, checkSize, SZ_ERROR_ARCHIVE)); |
|
1141 |
- for (i = (int)checkSize - 2; i >= 0; i--) |
|
1142 |
- if((buf[i] == 0x17 && buf[i + 1] == 0x6) || (buf[i] == 0x01 && buf[i + 1] == 0x04)) |
|
1143 |
- break; |
|
1144 |
- if (i < 0) |
|
1145 |
- return SZ_ERROR_ARCHIVE; |
|
1146 |
- nextHeaderSize = checkSize - i; |
|
1147 |
- nextHeaderOffset = readpos + i; |
|
1148 |
- if(nextHeaderOffset < k7zStartHeaderSize) |
|
1149 |
- return SZ_ERROR_INPUT_EOF; |
|
1150 |
- nextHeaderOffset -= k7zStartHeaderSize; |
|
1151 |
- nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize); |
|
1152 |
- RINOK(inStream->Seek(inStream, &curpos, SZ_SEEK_SET)); |
|
1153 |
- } |
|
1154 |
-/* aCaB - 2010-02-16 - END OF RECOVERY MODE */ |
|
1155 |
- |
|
1156 |
- nextHeaderSizeT = (size_t)nextHeaderSize; |
|
1157 |
- if (nextHeaderSizeT != nextHeaderSize) |
|
1158 |
- return SZ_ERROR_MEM; |
|
1159 |
- if (nextHeaderSizeT == 0) |
|
1160 |
- return SZ_OK; |
|
1161 |
- if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize || |
|
1162 |
- nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize) |
|
1163 |
- return SZ_ERROR_NO_ARCHIVE; |
|
1164 |
- |
|
1165 |
- { |
|
1166 |
- Int64 pos = 0; |
|
1167 |
- RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END)); |
|
1168 |
- if ((UInt64)pos < nextHeaderOffset || |
|
1169 |
- (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset || |
|
1170 |
- (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize) |
|
1171 |
- return SZ_ERROR_INPUT_EOF; |
|
1172 |
- } |
|
1173 |
- |
|
1174 |
- RINOK(LookInStream_SeekTo(inStream, k7zStartHeaderSize + nextHeaderOffset)); |
|
1175 |
- |
|
1176 |
- if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp)) |
|
1177 |
- return SZ_ERROR_MEM; |
|
1178 |
- |
|
1179 |
- res = LookInStream_Read(inStream, buffer.data, nextHeaderSizeT); |
|
1180 |
- if (res == SZ_OK) |
|
1181 |
- { |
|
1182 |
- res = SZ_ERROR_ARCHIVE; |
|
1183 |
- if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC) |
|
1184 |
- { |
|
1185 |
- CSzData sd; |
|
1186 |
- UInt64 type; |
|
1187 |
- sd.Data = buffer.data; |
|
1188 |
- sd.Size = buffer.size; |
|
1189 |
- res = SzReadID(&sd, &type); |
|
1190 |
- if (res == SZ_OK) |
|
1191 |
- { |
|
1192 |
- if (type == k7zIdEncodedHeader) |
|
1193 |
- { |
|
1194 |
- CBuf outBuffer; |
|
1195 |
- Buf_Init(&outBuffer); |
|
1196 |
- res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, p->startPosAfterHeader, allocTemp); |
|
1197 |
- if (res != SZ_OK) |
|
1198 |
- Buf_Free(&outBuffer, allocTemp); |
|
1199 |
- else |
|
1200 |
- { |
|
1201 |
- Buf_Free(&buffer, allocTemp); |
|
1202 |
- buffer.data = outBuffer.data; |
|
1203 |
- buffer.size = outBuffer.size; |
|
1204 |
- sd.Data = buffer.data; |
|
1205 |
- sd.Size = buffer.size; |
|
1206 |
- res = SzReadID(&sd, &type); |
|
1207 |
- } |
|
1208 |
- } |
|
1209 |
- } |
|
1210 |
- if (res == SZ_OK) |
|
1211 |
- { |
|
1212 |
- if (type == k7zIdHeader) |
|
1213 |
- res = SzReadHeader(p, &sd, allocMain, allocTemp); |
|
1214 |
- else |
|
1215 |
- res = SZ_ERROR_UNSUPPORTED; |
|
1216 |
- } |
|
1217 |
- } |
|
1218 |
- } |
|
1219 |
- Buf_Free(&buffer, allocTemp); |
|
1220 |
- return res; |
|
1221 |
-} |
|
1222 |
- |
|
1223 |
-SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp) |
|
1224 |
-{ |
|
1225 |
- SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp); |
|
1226 |
- if (res != SZ_OK) |
|
1227 |
- SzArEx_Free(p, allocMain); |
|
1228 |
- return res; |
|
1229 |
-} |
1230 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,41 +0,0 @@ |
1 |
-/* 7zIn.h -- 7z Input functions |
|
2 |
-2008-11-23 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#ifndef __7Z_IN_H |
|
5 |
-#define __7Z_IN_H |
|
6 |
- |
|
7 |
-#include "7zHeader.h" |
|
8 |
-#include "7zItem.h" |
|
9 |
- |
|
10 |
-typedef struct |
|
11 |
-{ |
|
12 |
- CSzAr db; |
|
13 |
- |
|
14 |
- UInt64 startPosAfterHeader; |
|
15 |
- UInt64 dataPos; |
|
16 |
- |
|
17 |
- UInt32 *FolderStartPackStreamIndex; |
|
18 |
- UInt64 *PackStreamStartPositions; |
|
19 |
- UInt32 *FolderStartFileIndex; |
|
20 |
- UInt32 *FileIndexToFolderIndexMap; |
|
21 |
-} CSzArEx; |
|
22 |
- |
|
23 |
-void SzArEx_Init(CSzArEx *p); |
|
24 |
-void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc); |
|
25 |
-UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder); |
|
26 |
-int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize); |
|
27 |
- |
|
28 |
-/* |
|
29 |
-Errors: |
|
30 |
-SZ_ERROR_NO_ARCHIVE |
|
31 |
-SZ_ERROR_ARCHIVE |
|
32 |
-SZ_ERROR_UNSUPPORTED |
|
33 |
-SZ_ERROR_MEM |
|
34 |
-SZ_ERROR_CRC |
|
35 |
-SZ_ERROR_INPUT_EOF |
|
36 |
-SZ_ERROR_FAIL |
|
37 |
-*/ |
|
38 |
- |
|
39 |
-SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp); |
|
40 |
- |
|
41 |
-#endif |
42 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,127 +0,0 @@ |
1 |
-/* 7zItem.c -- 7z Items |
|
2 |
-2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#include "7zItem.h" |
|
5 |
- |
|
6 |
-void SzCoderInfo_Init(CSzCoderInfo *p) |
|
7 |
-{ |
|
8 |
- Buf_Init(&p->Props); |
|
9 |
-} |
|
10 |
- |
|
11 |
-void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc) |
|
12 |
-{ |
|
13 |
- Buf_Free(&p->Props, alloc); |
|
14 |
- SzCoderInfo_Init(p); |
|
15 |
-} |
|
16 |
- |
|
17 |
-void SzFolder_Init(CSzFolder *p) |
|
18 |
-{ |
|
19 |
- p->Coders = 0; |
|
20 |
- p->BindPairs = 0; |
|
21 |
- p->PackStreams = 0; |
|
22 |
- p->UnpackSizes = 0; |
|
23 |
- p->NumCoders = 0; |
|
24 |
- p->NumBindPairs = 0; |
|
25 |
- p->NumPackStreams = 0; |
|
26 |
- p->UnpackCRCDefined = 0; |
|
27 |
- p->UnpackCRC = 0; |
|
28 |
- p->NumUnpackStreams = 0; |
|
29 |
-} |
|
30 |
- |
|
31 |
-void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc) |
|
32 |
-{ |
|
33 |
- UInt32 i; |
|
34 |
- if (p->Coders) |
|
35 |
- for (i = 0; i < p->NumCoders; i++) |
|
36 |
- SzCoderInfo_Free(&p->Coders[i], alloc); |
|
37 |
- IAlloc_Free(alloc, p->Coders); |
|
38 |
- IAlloc_Free(alloc, p->BindPairs); |
|
39 |
- IAlloc_Free(alloc, p->PackStreams); |
|
40 |
- IAlloc_Free(alloc, p->UnpackSizes); |
|
41 |
- SzFolder_Init(p); |
|
42 |
-} |
|
43 |
- |
|
44 |
-UInt32 SzFolder_GetNumOutStreams(CSzFolder *p) |
|
45 |
-{ |
|
46 |
- UInt32 result = 0; |
|
47 |
- UInt32 i; |
|
48 |
- for (i = 0; i < p->NumCoders; i++) |
|
49 |
- result += p->Coders[i].NumOutStreams; |
|
50 |
- return result; |
|
51 |
-} |
|
52 |
- |
|
53 |
-int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex) |
|
54 |
-{ |
|
55 |
- UInt32 i; |
|
56 |
- for (i = 0; i < p->NumBindPairs; i++) |
|
57 |
- if (p->BindPairs[i].InIndex == inStreamIndex) |
|
58 |
- return i; |
|
59 |
- return -1; |
|
60 |
-} |
|
61 |
- |
|
62 |
- |
|
63 |
-int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex) |
|
64 |
-{ |
|
65 |
- UInt32 i; |
|
66 |
- for (i = 0; i < p->NumBindPairs; i++) |
|
67 |
- if (p->BindPairs[i].OutIndex == outStreamIndex) |
|
68 |
- return i; |
|
69 |
- return -1; |
|
70 |
-} |
|
71 |
- |
|
72 |
-UInt64 SzFolder_GetUnpackSize(CSzFolder *p) |
|
73 |
-{ |
|
74 |
- int i = (int)SzFolder_GetNumOutStreams(p); |
|
75 |
- if (i == 0) |
|
76 |
- return 0; |
|
77 |
- for (i--; i >= 0; i--) |
|
78 |
- if (SzFolder_FindBindPairForOutStream(p, i) < 0) |
|
79 |
- return p->UnpackSizes[i]; |
|
80 |
- /* throw 1; */ |
|
81 |
- return 0; |
|
82 |
-} |
|
83 |
- |
|
84 |
-void SzFile_Init(CSzFileItem *p) |
|
85 |
-{ |
|
86 |
- p->HasStream = 1; |
|
87 |
- p->IsDir = 0; |
|
88 |
- p->IsAnti = 0; |
|
89 |
- p->FileCRCDefined = 0; |
|
90 |
- p->MTimeDefined = 0; |
|
91 |
- p->Name = 0; |
|
92 |
-} |
|
93 |
- |
|
94 |
-static void SzFile_Free(CSzFileItem *p, ISzAlloc *alloc) |
|
95 |
-{ |
|
96 |
- IAlloc_Free(alloc, p->Name); |
|
97 |
- SzFile_Init(p); |
|
98 |
-} |
|
99 |
- |
|
100 |
-void SzAr_Init(CSzAr *p) |
|
101 |
-{ |
|
102 |
- p->PackSizes = 0; |
|
103 |
- p->PackCRCsDefined = 0; |
|
104 |
- p->PackCRCs = 0; |
|
105 |
- p->Folders = 0; |
|
106 |
- p->Files = 0; |
|
107 |
- p->NumPackStreams = 0; |
|
108 |
- p->NumFolders = 0; |
|
109 |
- p->NumFiles = 0; |
|
110 |
-} |
|
111 |
- |
|
112 |
-void SzAr_Free(CSzAr *p, ISzAlloc *alloc) |
|
113 |
-{ |
|
114 |
- UInt32 i; |
|
115 |
- if (p->Folders) |
|
116 |
- for (i = 0; i < p->NumFolders; i++) |
|
117 |
- SzFolder_Free(&p->Folders[i], alloc); |
|
118 |
- if (p->Files) |
|
119 |
- for (i = 0; i < p->NumFiles; i++) |
|
120 |
- SzFile_Free(&p->Files[i], alloc); |
|
121 |
- IAlloc_Free(alloc, p->PackSizes); |
|
122 |
- IAlloc_Free(alloc, p->PackCRCsDefined); |
|
123 |
- IAlloc_Free(alloc, p->PackCRCs); |
|
124 |
- IAlloc_Free(alloc, p->Folders); |
|
125 |
- IAlloc_Free(alloc, p->Files); |
|
126 |
- SzAr_Init(p); |
|
127 |
-} |
128 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,84 +0,0 @@ |
1 |
-/* 7zItem.h -- 7z Items |
|
2 |
-2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#ifndef __7Z_ITEM_H |
|
5 |
-#define __7Z_ITEM_H |
|
6 |
- |
|
7 |
-#include "../../7zBuf.h" |
|
8 |
- |
|
9 |
-typedef struct |
|
10 |
-{ |
|
11 |
- UInt32 NumInStreams; |
|
12 |
- UInt32 NumOutStreams; |
|
13 |
- UInt64 MethodID; |
|
14 |
- CBuf Props; |
|
15 |
-} CSzCoderInfo; |
|
16 |
- |
|
17 |
-void SzCoderInfo_Init(CSzCoderInfo *p); |
|
18 |
-void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc); |
|
19 |
- |
|
20 |
-typedef struct |
|
21 |
-{ |
|
22 |
- UInt32 InIndex; |
|
23 |
- UInt32 OutIndex; |
|
24 |
-} CBindPair; |
|
25 |
- |
|
26 |
-typedef struct |
|
27 |
-{ |
|
28 |
- CSzCoderInfo *Coders; |
|
29 |
- CBindPair *BindPairs; |
|
30 |
- UInt32 *PackStreams; |
|
31 |
- UInt64 *UnpackSizes; |
|
32 |
- UInt32 NumCoders; |
|
33 |
- UInt32 NumBindPairs; |
|
34 |
- UInt32 NumPackStreams; |
|
35 |
- int UnpackCRCDefined; |
|
36 |
- UInt32 UnpackCRC; |
|
37 |
- |
|
38 |
- UInt32 NumUnpackStreams; |
|
39 |
-} CSzFolder; |
|
40 |
- |
|
41 |
-void SzFolder_Init(CSzFolder *p); |
|
42 |
-UInt64 SzFolder_GetUnpackSize(CSzFolder *p); |
|
43 |
-int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex); |
|
44 |
-UInt32 SzFolder_GetNumOutStreams(CSzFolder *p); |
|
45 |
-UInt64 SzFolder_GetUnpackSize(CSzFolder *p); |
|
46 |
- |
|
47 |
-typedef struct |
|
48 |
-{ |
|
49 |
- UInt32 Low; |
|
50 |
- UInt32 High; |
|
51 |
-} CNtfsFileTime; |
|
52 |
- |
|
53 |
-typedef struct |
|
54 |
-{ |
|
55 |
- CNtfsFileTime MTime; |
|
56 |
- UInt64 Size; |
|
57 |
- char *Name; |
|
58 |
- UInt32 FileCRC; |
|
59 |
- |
|
60 |
- Byte HasStream; |
|
61 |
- Byte IsDir; |
|
62 |
- Byte IsAnti; |
|
63 |
- Byte FileCRCDefined; |
|
64 |
- Byte MTimeDefined; |
|
65 |
-} CSzFileItem; |
|
66 |
- |
|
67 |
-void SzFile_Init(CSzFileItem *p); |
|
68 |
- |
|
69 |
-typedef struct |
|
70 |
-{ |
|
71 |
- UInt64 *PackSizes; |
|
72 |
- Byte *PackCRCsDefined; |
|
73 |
- UInt32 *PackCRCs; |
|
74 |
- CSzFolder *Folders; |
|
75 |
- CSzFileItem *Files; |
|
76 |
- UInt32 NumPackStreams; |
|
77 |
- UInt32 NumFolders; |
|
78 |
- UInt32 NumFiles; |
|
79 |
-} CSzAr; |
|
80 |
- |
|
81 |
-void SzAr_Init(CSzAr *p); |
|
82 |
-void SzAr_Free(CSzAr *p, ISzAlloc *alloc); |
|
83 |
- |
|
84 |
-#endif |
... | ... |
@@ -1,132 +1,132 @@ |
1 |
-/* Bcj2.c -- Converter for x86 code (BCJ2) |
|
2 |
-2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#include "Bcj2.h" |
|
5 |
- |
|
6 |
-#ifdef _LZMA_PROB32 |
|
7 |
-#define CProb UInt32 |
|
8 |
-#else |
|
9 |
-#define CProb UInt16 |
|
10 |
-#endif |
|
11 |
- |
|
12 |
-#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80) |
|
13 |
-#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1)) |
|
14 |
- |
|
15 |
-#define kNumTopBits 24 |
|
16 |
-#define kTopValue ((UInt32)1 << kNumTopBits) |
|
17 |
- |
|
18 |
-#define kNumBitModelTotalBits 11 |
|
19 |
-#define kBitModelTotal (1 << kNumBitModelTotalBits) |
|
20 |
-#define kNumMoveBits 5 |
|
21 |
- |
|
22 |
-#define RC_READ_BYTE (*buffer++) |
|
23 |
-#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; } |
|
24 |
-#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \ |
|
25 |
- { int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }} |
|
26 |
- |
|
27 |
-#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; } |
|
28 |
- |
|
29 |
-#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) |
|
30 |
-#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE; |
|
31 |
-#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE; |
|
32 |
- |
|
33 |
-int Bcj2_Decode( |
|
34 |
- const Byte *buf0, SizeT size0, |
|
35 |
- const Byte *buf1, SizeT size1, |
|
36 |
- const Byte *buf2, SizeT size2, |
|
37 |
- const Byte *buf3, SizeT size3, |
|
38 |
- Byte *outBuf, SizeT outSize) |
|
39 |
-{ |
|
40 |
- CProb p[256 + 2]; |
|
41 |
- SizeT inPos = 0, outPos = 0; |
|
42 |
- |
|
43 |
- const Byte *buffer, *bufferLim; |
|
44 |
- UInt32 range, code; |
|
45 |
- Byte prevByte = 0; |
|
46 |
- |
|
47 |
- unsigned int i; |
|
48 |
- for (i = 0; i < sizeof(p) / sizeof(p[0]); i++) |
|
49 |
- p[i] = kBitModelTotal >> 1; |
|
50 |
- |
|
51 |
- buffer = buf3; |
|
52 |
- bufferLim = buffer + size3; |
|
53 |
- RC_INIT2 |
|
54 |
- |
|
55 |
- if (outSize == 0) |
|
56 |
- return SZ_OK; |
|
57 |
- |
|
58 |
- for (;;) |
|
59 |
- { |
|
60 |
- Byte b; |
|
61 |
- CProb *prob; |
|
62 |
- UInt32 bound; |
|
63 |
- UInt32 ttt; |
|
64 |
- |
|
65 |
- SizeT limit = size0 - inPos; |
|
66 |
- if (outSize - outPos < limit) |
|
67 |
- limit = outSize - outPos; |
|
68 |
- while (limit != 0) |
|
69 |
- { |
|
70 |
- Byte b = buf0[inPos]; |
|
71 |
- outBuf[outPos++] = b; |
|
72 |
- if (IsJ(prevByte, b)) |
|
73 |
- break; |
|
74 |
- inPos++; |
|
75 |
- prevByte = b; |
|
76 |
- limit--; |
|
77 |
- } |
|
78 |
- |
|
79 |
- if (limit == 0 || outPos == outSize) |
|
80 |
- break; |
|
81 |
- |
|
82 |
- b = buf0[inPos++]; |
|
83 |
- |
|
84 |
- if (b == 0xE8) |
|
85 |
- prob = p + prevByte; |
|
86 |
- else if (b == 0xE9) |
|
87 |
- prob = p + 256; |
|
88 |
- else |
|
89 |
- prob = p + 257; |
|
90 |
- |
|
91 |
- IF_BIT_0(prob) |
|
92 |
- { |
|
93 |
- UPDATE_0(prob) |
|
94 |
- prevByte = b; |
|
95 |
- } |
|
96 |
- else |
|
97 |
- { |
|
98 |
- UInt32 dest; |
|
99 |
- const Byte *v; |
|
100 |
- UPDATE_1(prob) |
|
101 |
- if (b == 0xE8) |
|
102 |
- { |
|
103 |
- v = buf1; |
|
104 |
- if (size1 < 4) |
|
105 |
- return SZ_ERROR_DATA; |
|
106 |
- buf1 += 4; |
|
107 |
- size1 -= 4; |
|
108 |
- } |
|
109 |
- else |
|
110 |
- { |
|
111 |
- v = buf2; |
|
112 |
- if (size2 < 4) |
|
113 |
- return SZ_ERROR_DATA; |
|
114 |
- buf2 += 4; |
|
115 |
- size2 -= 4; |
|
116 |
- } |
|
117 |
- dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) | |
|
118 |
- ((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4); |
|
119 |
- outBuf[outPos++] = (Byte)dest; |
|
120 |
- if (outPos == outSize) |
|
121 |
- break; |
|
122 |
- outBuf[outPos++] = (Byte)(dest >> 8); |
|
123 |
- if (outPos == outSize) |
|
124 |
- break; |
|
125 |
- outBuf[outPos++] = (Byte)(dest >> 16); |
|
126 |
- if (outPos == outSize) |
|
127 |
- break; |
|
128 |
- outBuf[outPos++] = prevByte = (Byte)(dest >> 24); |
|
129 |
- } |
|
130 |
- } |
|
131 |
- return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA; |
|
132 |
-} |
|
1 |
+/* Bcj2.c -- Converter for x86 code (BCJ2) |
|
2 |
+2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#include "Bcj2.h" |
|
5 |
+ |
|
6 |
+#ifdef _LZMA_PROB32 |
|
7 |
+#define CProb UInt32 |
|
8 |
+#else |
|
9 |
+#define CProb UInt16 |
|
10 |
+#endif |
|
11 |
+ |
|
12 |
+#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80) |
|
13 |
+#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1)) |
|
14 |
+ |
|
15 |
+#define kNumTopBits 24 |
|
16 |
+#define kTopValue ((UInt32)1 << kNumTopBits) |
|
17 |
+ |
|
18 |
+#define kNumBitModelTotalBits 11 |
|
19 |
+#define kBitModelTotal (1 << kNumBitModelTotalBits) |
|
20 |
+#define kNumMoveBits 5 |
|
21 |
+ |
|
22 |
+#define RC_READ_BYTE (*buffer++) |
|
23 |
+#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; } |
|
24 |
+#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \ |
|
25 |
+ { int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }} |
|
26 |
+ |
|
27 |
+#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; } |
|
28 |
+ |
|
29 |
+#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) |
|
30 |
+#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE; |
|
31 |
+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE; |
|
32 |
+ |
|
33 |
+int Bcj2_Decode( |
|
34 |
+ const Byte *buf0, SizeT size0, |
|
35 |
+ const Byte *buf1, SizeT size1, |
|
36 |
+ const Byte *buf2, SizeT size2, |
|
37 |
+ const Byte *buf3, SizeT size3, |
|
38 |
+ Byte *outBuf, SizeT outSize) |
|
39 |
+{ |
|
40 |
+ CProb p[256 + 2]; |
|
41 |
+ SizeT inPos = 0, outPos = 0; |
|
42 |
+ |
|
43 |
+ const Byte *buffer, *bufferLim; |
|
44 |
+ UInt32 range, code; |
|
45 |
+ Byte prevByte = 0; |
|
46 |
+ |
|
47 |
+ unsigned int i; |
|
48 |
+ for (i = 0; i < sizeof(p) / sizeof(p[0]); i++) |
|
49 |
+ p[i] = kBitModelTotal >> 1; |
|
50 |
+ |
|
51 |
+ buffer = buf3; |
|
52 |
+ bufferLim = buffer + size3; |
|
53 |
+ RC_INIT2 |
|
54 |
+ |
|
55 |
+ if (outSize == 0) |
|
56 |
+ return SZ_OK; |
|
57 |
+ |
|
58 |
+ for (;;) |
|
59 |
+ { |
|
60 |
+ Byte b; |
|
61 |
+ CProb *prob; |
|
62 |
+ UInt32 bound; |
|
63 |
+ UInt32 ttt; |
|
64 |
+ |
|
65 |
+ SizeT limit = size0 - inPos; |
|
66 |
+ if (outSize - outPos < limit) |
|
67 |
+ limit = outSize - outPos; |
|
68 |
+ while (limit != 0) |
|
69 |
+ { |
|
70 |
+ Byte b = buf0[inPos]; |
|
71 |
+ outBuf[outPos++] = b; |
|
72 |
+ if (IsJ(prevByte, b)) |
|
73 |
+ break; |
|
74 |
+ inPos++; |
|
75 |
+ prevByte = b; |
|
76 |
+ limit--; |
|
77 |
+ } |
|
78 |
+ |
|
79 |
+ if (limit == 0 || outPos == outSize) |
|
80 |
+ break; |
|
81 |
+ |
|
82 |
+ b = buf0[inPos++]; |
|
83 |
+ |
|
84 |
+ if (b == 0xE8) |
|
85 |
+ prob = p + prevByte; |
|
86 |
+ else if (b == 0xE9) |
|
87 |
+ prob = p + 256; |
|
88 |
+ else |
|
89 |
+ prob = p + 257; |
|
90 |
+ |
|
91 |
+ IF_BIT_0(prob) |
|
92 |
+ { |
|
93 |
+ UPDATE_0(prob) |
|
94 |
+ prevByte = b; |
|
95 |
+ } |
|
96 |
+ else |
|
97 |
+ { |
|
98 |
+ UInt32 dest; |
|
99 |
+ const Byte *v; |
|
100 |
+ UPDATE_1(prob) |
|
101 |
+ if (b == 0xE8) |
|
102 |
+ { |
|
103 |
+ v = buf1; |
|
104 |
+ if (size1 < 4) |
|
105 |
+ return SZ_ERROR_DATA; |
|
106 |
+ buf1 += 4; |
|
107 |
+ size1 -= 4; |
|
108 |
+ } |
|
109 |
+ else |
|
110 |
+ { |
|
111 |
+ v = buf2; |
|
112 |
+ if (size2 < 4) |
|
113 |
+ return SZ_ERROR_DATA; |
|
114 |
+ buf2 += 4; |
|
115 |
+ size2 -= 4; |
|
116 |
+ } |
|
117 |
+ dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) | |
|
118 |
+ ((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4); |
|
119 |
+ outBuf[outPos++] = (Byte)dest; |
|
120 |
+ if (outPos == outSize) |
|
121 |
+ break; |
|
122 |
+ outBuf[outPos++] = (Byte)(dest >> 8); |
|
123 |
+ if (outPos == outSize) |
|
124 |
+ break; |
|
125 |
+ outBuf[outPos++] = (Byte)(dest >> 16); |
|
126 |
+ if (outPos == outSize) |
|
127 |
+ break; |
|
128 |
+ outBuf[outPos++] = prevByte = (Byte)(dest >> 24); |
|
129 |
+ } |
|
130 |
+ } |
|
131 |
+ return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA; |
|
132 |
+} |
... | ... |
@@ -1,30 +1,38 @@ |
1 |
-/* Bcj2.h -- Converter for x86 code (BCJ2) |
|
2 |
-2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#ifndef __BCJ2_H |
|
5 |
-#define __BCJ2_H |
|
6 |
- |
|
7 |
-#include "Types.h" |
|
8 |
- |
|
9 |
-/* |
|
10 |
-Conditions: |
|
11 |
- outSize <= FullOutputSize, |
|
12 |
- where FullOutputSize is full size of output stream of x86_2 filter. |
|
13 |
- |
|
14 |
-If buf0 overlaps outBuf, there are two required conditions: |
|
15 |
- 1) (buf0 >= outBuf) |
|
16 |
- 2) (buf0 + size0 >= outBuf + FullOutputSize). |
|
17 |
- |
|
18 |
-Returns: |
|
19 |
- SZ_OK |
|
20 |
- SZ_ERROR_DATA - Data error |
|
21 |
-*/ |
|
22 |
- |
|
23 |
-int Bcj2_Decode( |
|
24 |
- const Byte *buf0, SizeT size0, |
|
25 |
- const Byte *buf1, SizeT size1, |
|
26 |
- const Byte *buf2, SizeT size2, |
|
27 |
- const Byte *buf3, SizeT size3, |
|
28 |
- Byte *outBuf, SizeT outSize); |
|
29 |
- |
|
30 |
-#endif |
|
1 |
+/* Bcj2.h -- Converter for x86 code (BCJ2) |
|
2 |
+2009-02-07 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#ifndef __BCJ2_H |
|
5 |
+#define __BCJ2_H |
|
6 |
+ |
|
7 |
+#include "Types.h" |
|
8 |
+ |
|
9 |
+#ifdef __cplusplus |
|
10 |
+extern "C" { |
|
11 |
+#endif |
|
12 |
+ |
|
13 |
+/* |
|
14 |
+Conditions: |
|
15 |
+ outSize <= FullOutputSize, |
|
16 |
+ where FullOutputSize is full size of output stream of x86_2 filter. |
|
17 |
+ |
|
18 |
+If buf0 overlaps outBuf, there are two required conditions: |
|
19 |
+ 1) (buf0 >= outBuf) |
|
20 |
+ 2) (buf0 + size0 >= outBuf + FullOutputSize). |
|
21 |
+ |
|
22 |
+Returns: |
|
23 |
+ SZ_OK |
|
24 |
+ SZ_ERROR_DATA - Data error |
|
25 |
+*/ |
|
26 |
+ |
|
27 |
+int Bcj2_Decode( |
|
28 |
+ const Byte *buf0, SizeT size0, |
|
29 |
+ const Byte *buf1, SizeT size1, |
|
30 |
+ const Byte *buf2, SizeT size2, |
|
31 |
+ const Byte *buf3, SizeT size3, |
|
32 |
+ Byte *outBuf, SizeT outSize); |
|
33 |
+ |
|
34 |
+#ifdef __cplusplus |
|
35 |
+} |
|
36 |
+#endif |
|
37 |
+ |
|
38 |
+#endif |
... | ... |
@@ -1,133 +1,133 @@ |
1 |
-/* Bra.c -- Converters for RISC code |
|
2 |
-2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#include "Bra.h" |
|
5 |
- |
|
6 |
-SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) |
|
7 |
-{ |
|
8 |
- SizeT i; |
|
9 |
- if (size < 4) |
|
10 |
- return 0; |
|
11 |
- size -= 4; |
|
12 |
- ip += 8; |
|
13 |
- for (i = 0; i <= size; i += 4) |
|
14 |
- { |
|
15 |
- if (data[i + 3] == 0xEB) |
|
16 |
- { |
|
17 |
- UInt32 dest; |
|
18 |
- UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]); |
|
19 |
- src <<= 2; |
|
20 |
- if (encoding) |
|
21 |
- dest = ip + (UInt32)i + src; |
|
22 |
- else |
|
23 |
- dest = src - (ip + (UInt32)i); |
|
24 |
- dest >>= 2; |
|
25 |
- data[i + 2] = (Byte)(dest >> 16); |
|
26 |
- data[i + 1] = (Byte)(dest >> 8); |
|
27 |
- data[i + 0] = (Byte)dest; |
|
28 |
- } |
|
29 |
- } |
|
30 |
- return i; |
|
31 |
-} |
|
32 |
- |
|
33 |
-SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) |
|
34 |
-{ |
|
35 |
- SizeT i; |
|
36 |
- if (size < 4) |
|
37 |
- return 0; |
|
38 |
- size -= 4; |
|
39 |
- ip += 4; |
|
40 |
- for (i = 0; i <= size; i += 2) |
|
41 |
- { |
|
42 |
- if ((data[i + 1] & 0xF8) == 0xF0 && |
|
43 |
- (data[i + 3] & 0xF8) == 0xF8) |
|
44 |
- { |
|
45 |
- UInt32 dest; |
|
46 |
- UInt32 src = |
|
47 |
- (((UInt32)data[i + 1] & 0x7) << 19) | |
|
48 |
- ((UInt32)data[i + 0] << 11) | |
|
49 |
- (((UInt32)data[i + 3] & 0x7) << 8) | |
|
50 |
- (data[i + 2]); |
|
51 |
- |
|
52 |
- src <<= 1; |
|
53 |
- if (encoding) |
|
54 |
- dest = ip + (UInt32)i + src; |
|
55 |
- else |
|
56 |
- dest = src - (ip + (UInt32)i); |
|
57 |
- dest >>= 1; |
|
58 |
- |
|
59 |
- data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7)); |
|
60 |
- data[i + 0] = (Byte)(dest >> 11); |
|
61 |
- data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7)); |
|
62 |
- data[i + 2] = (Byte)dest; |
|
63 |
- i += 2; |
|
64 |
- } |
|
65 |
- } |
|
66 |
- return i; |
|
67 |
-} |
|
68 |
- |
|
69 |
-SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) |
|
70 |
-{ |
|
71 |
- SizeT i; |
|
72 |
- if (size < 4) |
|
73 |
- return 0; |
|
74 |
- size -= 4; |
|
75 |
- for (i = 0; i <= size; i += 4) |
|
76 |
- { |
|
77 |
- if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1) |
|
78 |
- { |
|
79 |
- UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) | |
|
80 |
- ((UInt32)data[i + 1] << 16) | |
|
81 |
- ((UInt32)data[i + 2] << 8) | |
|
82 |
- ((UInt32)data[i + 3] & (~3)); |
|
83 |
- |
|
84 |
- UInt32 dest; |
|
85 |
- if (encoding) |
|
86 |
- dest = ip + (UInt32)i + src; |
|
87 |
- else |
|
88 |
- dest = src - (ip + (UInt32)i); |
|
89 |
- data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3)); |
|
90 |
- data[i + 1] = (Byte)(dest >> 16); |
|
91 |
- data[i + 2] = (Byte)(dest >> 8); |
|
92 |
- data[i + 3] &= 0x3; |
|
93 |
- data[i + 3] |= dest; |
|
94 |
- } |
|
95 |
- } |
|
96 |
- return i; |
|
97 |
-} |
|
98 |
- |
|
99 |
-SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) |
|
100 |
-{ |
|
101 |
- UInt32 i; |
|
102 |
- if (size < 4) |
|
103 |
- return 0; |
|
104 |
- size -= 4; |
|
105 |
- for (i = 0; i <= size; i += 4) |
|
106 |
- { |
|
107 |
- if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) || |
|
108 |
- (data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)) |
|
109 |
- { |
|
110 |
- UInt32 src = |
|
111 |
- ((UInt32)data[i + 0] << 24) | |
|
112 |
- ((UInt32)data[i + 1] << 16) | |
|
113 |
- ((UInt32)data[i + 2] << 8) | |
|
114 |
- ((UInt32)data[i + 3]); |
|
115 |
- UInt32 dest; |
|
116 |
- |
|
117 |
- src <<= 2; |
|
118 |
- if (encoding) |
|
119 |
- dest = ip + i + src; |
|
120 |
- else |
|
121 |
- dest = src - (ip + i); |
|
122 |
- dest >>= 2; |
|
123 |
- |
|
124 |
- dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000; |
|
125 |
- |
|
126 |
- data[i + 0] = (Byte)(dest >> 24); |
|
127 |
- data[i + 1] = (Byte)(dest >> 16); |
|
128 |
- data[i + 2] = (Byte)(dest >> 8); |
|
129 |
- data[i + 3] = (Byte)dest; |
|
130 |
- } |
|
131 |
- } |
|
132 |
- return i; |
|
133 |
-} |
|
1 |
+/* Bra.c -- Converters for RISC code |
|
2 |
+2010-04-16 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#include "Bra.h" |
|
5 |
+ |
|
6 |
+SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) |
|
7 |
+{ |
|
8 |
+ SizeT i; |
|
9 |
+ if (size < 4) |
|
10 |
+ return 0; |
|
11 |
+ size -= 4; |
|
12 |
+ ip += 8; |
|
13 |
+ for (i = 0; i <= size; i += 4) |
|
14 |
+ { |
|
15 |
+ if (data[i + 3] == 0xEB) |
|
16 |
+ { |
|
17 |
+ UInt32 dest; |
|
18 |
+ UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]); |
|
19 |
+ src <<= 2; |
|
20 |
+ if (encoding) |
|
21 |
+ dest = ip + (UInt32)i + src; |
|
22 |
+ else |
|
23 |
+ dest = src - (ip + (UInt32)i); |
|
24 |
+ dest >>= 2; |
|
25 |
+ data[i + 2] = (Byte)(dest >> 16); |
|
26 |
+ data[i + 1] = (Byte)(dest >> 8); |
|
27 |
+ data[i + 0] = (Byte)dest; |
|
28 |
+ } |
|
29 |
+ } |
|
30 |
+ return i; |
|
31 |
+} |
|
32 |
+ |
|
33 |
+SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) |
|
34 |
+{ |
|
35 |
+ SizeT i; |
|
36 |
+ if (size < 4) |
|
37 |
+ return 0; |
|
38 |
+ size -= 4; |
|
39 |
+ ip += 4; |
|
40 |
+ for (i = 0; i <= size; i += 2) |
|
41 |
+ { |
|
42 |
+ if ((data[i + 1] & 0xF8) == 0xF0 && |
|
43 |
+ (data[i + 3] & 0xF8) == 0xF8) |
|
44 |
+ { |
|
45 |
+ UInt32 dest; |
|
46 |
+ UInt32 src = |
|
47 |
+ (((UInt32)data[i + 1] & 0x7) << 19) | |
|
48 |
+ ((UInt32)data[i + 0] << 11) | |
|
49 |
+ (((UInt32)data[i + 3] & 0x7) << 8) | |
|
50 |
+ (data[i + 2]); |
|
51 |
+ |
|
52 |
+ src <<= 1; |
|
53 |
+ if (encoding) |
|
54 |
+ dest = ip + (UInt32)i + src; |
|
55 |
+ else |
|
56 |
+ dest = src - (ip + (UInt32)i); |
|
57 |
+ dest >>= 1; |
|
58 |
+ |
|
59 |
+ data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7)); |
|
60 |
+ data[i + 0] = (Byte)(dest >> 11); |
|
61 |
+ data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7)); |
|
62 |
+ data[i + 2] = (Byte)dest; |
|
63 |
+ i += 2; |
|
64 |
+ } |
|
65 |
+ } |
|
66 |
+ return i; |
|
67 |
+} |
|
68 |
+ |
|
69 |
+SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) |
|
70 |
+{ |
|
71 |
+ SizeT i; |
|
72 |
+ if (size < 4) |
|
73 |
+ return 0; |
|
74 |
+ size -= 4; |
|
75 |
+ for (i = 0; i <= size; i += 4) |
|
76 |
+ { |
|
77 |
+ if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1) |
|
78 |
+ { |
|
79 |
+ UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) | |
|
80 |
+ ((UInt32)data[i + 1] << 16) | |
|
81 |
+ ((UInt32)data[i + 2] << 8) | |
|
82 |
+ ((UInt32)data[i + 3] & (~3)); |
|
83 |
+ |
|
84 |
+ UInt32 dest; |
|
85 |
+ if (encoding) |
|
86 |
+ dest = ip + (UInt32)i + src; |
|
87 |
+ else |
|
88 |
+ dest = src - (ip + (UInt32)i); |
|
89 |
+ data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3)); |
|
90 |
+ data[i + 1] = (Byte)(dest >> 16); |
|
91 |
+ data[i + 2] = (Byte)(dest >> 8); |
|
92 |
+ data[i + 3] &= 0x3; |
|
93 |
+ data[i + 3] |= dest; |
|
94 |
+ } |
|
95 |
+ } |
|
96 |
+ return i; |
|
97 |
+} |
|
98 |
+ |
|
99 |
+SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) |
|
100 |
+{ |
|
101 |
+ UInt32 i; |
|
102 |
+ if (size < 4) |
|
103 |
+ return 0; |
|
104 |
+ size -= 4; |
|
105 |
+ for (i = 0; i <= size; i += 4) |
|
106 |
+ { |
|
107 |
+ if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) || |
|
108 |
+ (data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)) |
|
109 |
+ { |
|
110 |
+ UInt32 src = |
|
111 |
+ ((UInt32)data[i + 0] << 24) | |
|
112 |
+ ((UInt32)data[i + 1] << 16) | |
|
113 |
+ ((UInt32)data[i + 2] << 8) | |
|
114 |
+ ((UInt32)data[i + 3]); |
|
115 |
+ UInt32 dest; |
|
116 |
+ |
|
117 |
+ src <<= 2; |
|
118 |
+ if (encoding) |
|
119 |
+ dest = ip + i + src; |
|
120 |
+ else |
|
121 |
+ dest = src - (ip + i); |
|
122 |
+ dest >>= 2; |
|
123 |
+ |
|
124 |
+ dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000; |
|
125 |
+ |
|
126 |
+ data[i + 0] = (Byte)(dest >> 24); |
|
127 |
+ data[i + 1] = (Byte)(dest >> 16); |
|
128 |
+ data[i + 2] = (Byte)(dest >> 8); |
|
129 |
+ data[i + 3] = (Byte)dest; |
|
130 |
+ } |
|
131 |
+ } |
|
132 |
+ return i; |
|
133 |
+} |
... | ... |
@@ -1,60 +1,68 @@ |
1 |
-/* Bra.h -- Branch converters for executables |
|
2 |
-2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#ifndef __BRA_H |
|
5 |
-#define __BRA_H |
|
6 |
- |
|
7 |
-#include "Types.h" |
|
8 |
- |
|
9 |
-/* |
|
10 |
-These functions convert relative addresses to absolute addresses |
|
11 |
-in CALL instructions to increase the compression ratio. |
|
12 |
- |
|
13 |
- In: |
|
14 |
- data - data buffer |
|
15 |
- size - size of data |
|
16 |
- ip - current virtual Instruction Pinter (IP) value |
|
17 |
- state - state variable for x86 converter |
|
18 |
- encoding - 0 (for decoding), 1 (for encoding) |
|
19 |
- |
|
20 |
- Out: |
|
21 |
- state - state variable for x86 converter |
|
22 |
- |
|
23 |
- Returns: |
|
24 |
- The number of processed bytes. If you call these functions with multiple calls, |
|
25 |
- you must start next call with first byte after block of processed bytes. |
|
26 |
- |
|
27 |
- Type Endian Alignment LookAhead |
|
28 |
- |
|
29 |
- x86 little 1 4 |
|
30 |
- ARMT little 2 2 |
|
31 |
- ARM little 4 0 |
|
32 |
- PPC big 4 0 |
|
33 |
- SPARC big 4 0 |
|
34 |
- IA64 little 16 0 |
|
35 |
- |
|
36 |
- size must be >= Alignment + LookAhead, if it's not last block. |
|
37 |
- If (size < Alignment + LookAhead), converter returns 0. |
|
38 |
- |
|
39 |
- Example: |
|
40 |
- |
|
41 |
- UInt32 ip = 0; |
|
42 |
- for () |
|
43 |
- { |
|
44 |
- ; size must be >= Alignment + LookAhead, if it's not last block |
|
45 |
- SizeT processed = Convert(data, size, ip, 1); |
|
46 |
- data += processed; |
|
47 |
- size -= processed; |
|
48 |
- ip += processed; |
|
49 |
- } |
|
50 |
-*/ |
|
51 |
- |
|
52 |
-#define x86_Convert_Init(state) { state = 0; } |
|
53 |
-SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding); |
|
54 |
-SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); |
|
55 |
-SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); |
|
56 |
-SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); |
|
57 |
-SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); |
|
58 |
-SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); |
|
59 |
- |
|
60 |
-#endif |
|
1 |
+/* Bra.h -- Branch converters for executables |
|
2 |
+2009-02-07 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#ifndef __BRA_H |
|
5 |
+#define __BRA_H |
|
6 |
+ |
|
7 |
+#include "Types.h" |
|
8 |
+ |
|
9 |
+#ifdef __cplusplus |
|
10 |
+extern "C" { |
|
11 |
+#endif |
|
12 |
+ |
|
13 |
+/* |
|
14 |
+These functions convert relative addresses to absolute addresses |
|
15 |
+in CALL instructions to increase the compression ratio. |
|
16 |
+ |
|
17 |
+ In: |
|
18 |
+ data - data buffer |
|
19 |
+ size - size of data |
|
20 |
+ ip - current virtual Instruction Pinter (IP) value |
|
21 |
+ state - state variable for x86 converter |
|
22 |
+ encoding - 0 (for decoding), 1 (for encoding) |
|
23 |
+ |
|
24 |
+ Out: |
|
25 |
+ state - state variable for x86 converter |
|
26 |
+ |
|
27 |
+ Returns: |
|
28 |
+ The number of processed bytes. If you call these functions with multiple calls, |
|
29 |
+ you must start next call with first byte after block of processed bytes. |
|
30 |
+ |
|
31 |
+ Type Endian Alignment LookAhead |
|
32 |
+ |
|
33 |
+ x86 little 1 4 |
|
34 |
+ ARMT little 2 2 |
|
35 |
+ ARM little 4 0 |
|
36 |
+ PPC big 4 0 |
|
37 |
+ SPARC big 4 0 |
|
38 |
+ IA64 little 16 0 |
|
39 |
+ |
|
40 |
+ size must be >= Alignment + LookAhead, if it's not last block. |
|
41 |
+ If (size < Alignment + LookAhead), converter returns 0. |
|
42 |
+ |
|
43 |
+ Example: |
|
44 |
+ |
|
45 |
+ UInt32 ip = 0; |
|
46 |
+ for () |
|
47 |
+ { |
|
48 |
+ ; size must be >= Alignment + LookAhead, if it's not last block |
|
49 |
+ SizeT processed = Convert(data, size, ip, 1); |
|
50 |
+ data += processed; |
|
51 |
+ size -= processed; |
|
52 |
+ ip += processed; |
|
53 |
+ } |
|
54 |
+*/ |
|
55 |
+ |
|
56 |
+#define x86_Convert_Init(state) { state = 0; } |
|
57 |
+SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding); |
|
58 |
+SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); |
|
59 |
+SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); |
|
60 |
+SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); |
|
61 |
+SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); |
|
62 |
+SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); |
|
63 |
+ |
|
64 |
+#ifdef __cplusplus |
|
65 |
+} |
|
66 |
+#endif |
|
67 |
+ |
|
68 |
+#endif |
... | ... |
@@ -1,85 +1,85 @@ |
1 |
-/* Bra86.c -- Converter for x86 code (BCJ) |
|
2 |
-2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#include "Bra.h" |
|
5 |
- |
|
6 |
-#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF) |
|
7 |
- |
|
8 |
-const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0}; |
|
9 |
-const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3}; |
|
10 |
- |
|
11 |
-SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding) |
|
12 |
-{ |
|
13 |
- SizeT bufferPos = 0, prevPosT; |
|
14 |
- UInt32 prevMask = *state & 0x7; |
|
15 |
- if (size < 5) |
|
16 |
- return 0; |
|
17 |
- ip += 5; |
|
18 |
- prevPosT = (SizeT)0 - 1; |
|
19 |
- |
|
20 |
- for (;;) |
|
21 |
- { |
|
22 |
- Byte *p = data + bufferPos; |
|
23 |
- Byte *limit = data + size - 4; |
|
24 |
- for (; p < limit; p++) |
|
25 |
- if ((*p & 0xFE) == 0xE8) |
|
26 |
- break; |
|
27 |
- bufferPos = (SizeT)(p - data); |
|
28 |
- if (p >= limit) |
|
29 |
- break; |
|
30 |
- prevPosT = bufferPos - prevPosT; |
|
31 |
- if (prevPosT > 3) |
|
32 |
- prevMask = 0; |
|
33 |
- else |
|
34 |
- { |
|
35 |
- prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7; |
|
36 |
- if (prevMask != 0) |
|
37 |
- { |
|
38 |
- Byte b = p[4 - kMaskToBitNumber[prevMask]]; |
|
39 |
- if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b)) |
|
40 |
- { |
|
41 |
- prevPosT = bufferPos; |
|
42 |
- prevMask = ((prevMask << 1) & 0x7) | 1; |
|
43 |
- bufferPos++; |
|
44 |
- continue; |
|
45 |
- } |
|
46 |
- } |
|
47 |
- } |
|
48 |
- prevPosT = bufferPos; |
|
49 |
- |
|
50 |
- if (Test86MSByte(p[4])) |
|
51 |
- { |
|
52 |
- UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]); |
|
53 |
- UInt32 dest; |
|
54 |
- for (;;) |
|
55 |
- { |
|
56 |
- Byte b; |
|
57 |
- int index; |
|
58 |
- if (encoding) |
|
59 |
- dest = (ip + (UInt32)bufferPos) + src; |
|
60 |
- else |
|
61 |
- dest = src - (ip + (UInt32)bufferPos); |
|
62 |
- if (prevMask == 0) |
|
63 |
- break; |
|
64 |
- index = kMaskToBitNumber[prevMask] * 8; |
|
65 |
- b = (Byte)(dest >> (24 - index)); |
|
66 |
- if (!Test86MSByte(b)) |
|
67 |
- break; |
|
68 |
- src = dest ^ ((1 << (32 - index)) - 1); |
|
69 |
- } |
|
70 |
- p[4] = (Byte)(~(((dest >> 24) & 1) - 1)); |
|
71 |
- p[3] = (Byte)(dest >> 16); |
|
72 |
- p[2] = (Byte)(dest >> 8); |
|
73 |
- p[1] = (Byte)dest; |
|
74 |
- bufferPos += 5; |
|
75 |
- } |
|
76 |
- else |
|
77 |
- { |
|
78 |
- prevMask = ((prevMask << 1) & 0x7) | 1; |
|
79 |
- bufferPos++; |
|
80 |
- } |
|
81 |
- } |
|
82 |
- prevPosT = bufferPos - prevPosT; |
|
83 |
- *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7)); |
|
84 |
- return bufferPos; |
|
85 |
-} |
|
1 |
+/* Bra86.c -- Converter for x86 code (BCJ) |
|
2 |
+2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#include "Bra.h" |
|
5 |
+ |
|
6 |
+#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF) |
|
7 |
+ |
|
8 |
+const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0}; |
|
9 |
+const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3}; |
|
10 |
+ |
|
11 |
+SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding) |
|
12 |
+{ |
|
13 |
+ SizeT bufferPos = 0, prevPosT; |
|
14 |
+ UInt32 prevMask = *state & 0x7; |
|
15 |
+ if (size < 5) |
|
16 |
+ return 0; |
|
17 |
+ ip += 5; |
|
18 |
+ prevPosT = (SizeT)0 - 1; |
|
19 |
+ |
|
20 |
+ for (;;) |
|
21 |
+ { |
|
22 |
+ Byte *p = data + bufferPos; |
|
23 |
+ Byte *limit = data + size - 4; |
|
24 |
+ for (; p < limit; p++) |
|
25 |
+ if ((*p & 0xFE) == 0xE8) |
|
26 |
+ break; |
|
27 |
+ bufferPos = (SizeT)(p - data); |
|
28 |
+ if (p >= limit) |
|
29 |
+ break; |
|
30 |
+ prevPosT = bufferPos - prevPosT; |
|
31 |
+ if (prevPosT > 3) |
|
32 |
+ prevMask = 0; |
|
33 |
+ else |
|
34 |
+ { |
|
35 |
+ prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7; |
|
36 |
+ if (prevMask != 0) |
|
37 |
+ { |
|
38 |
+ Byte b = p[4 - kMaskToBitNumber[prevMask]]; |
|
39 |
+ if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b)) |
|
40 |
+ { |
|
41 |
+ prevPosT = bufferPos; |
|
42 |
+ prevMask = ((prevMask << 1) & 0x7) | 1; |
|
43 |
+ bufferPos++; |
|
44 |
+ continue; |
|
45 |
+ } |
|
46 |
+ } |
|
47 |
+ } |
|
48 |
+ prevPosT = bufferPos; |
|
49 |
+ |
|
50 |
+ if (Test86MSByte(p[4])) |
|
51 |
+ { |
|
52 |
+ UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]); |
|
53 |
+ UInt32 dest; |
|
54 |
+ for (;;) |
|
55 |
+ { |
|
56 |
+ Byte b; |
|
57 |
+ int index; |
|
58 |
+ if (encoding) |
|
59 |
+ dest = (ip + (UInt32)bufferPos) + src; |
|
60 |
+ else |
|
61 |
+ dest = src - (ip + (UInt32)bufferPos); |
|
62 |
+ if (prevMask == 0) |
|
63 |
+ break; |
|
64 |
+ index = kMaskToBitNumber[prevMask] * 8; |
|
65 |
+ b = (Byte)(dest >> (24 - index)); |
|
66 |
+ if (!Test86MSByte(b)) |
|
67 |
+ break; |
|
68 |
+ src = dest ^ ((1 << (32 - index)) - 1); |
|
69 |
+ } |
|
70 |
+ p[4] = (Byte)(~(((dest >> 24) & 1) - 1)); |
|
71 |
+ p[3] = (Byte)(dest >> 16); |
|
72 |
+ p[2] = (Byte)(dest >> 8); |
|
73 |
+ p[1] = (Byte)dest; |
|
74 |
+ bufferPos += 5; |
|
75 |
+ } |
|
76 |
+ else |
|
77 |
+ { |
|
78 |
+ prevMask = ((prevMask << 1) & 0x7) | 1; |
|
79 |
+ bufferPos++; |
|
80 |
+ } |
|
81 |
+ } |
|
82 |
+ prevPosT = bufferPos - prevPosT; |
|
83 |
+ *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7)); |
|
84 |
+ return bufferPos; |
|
85 |
+} |
86 | 86 |
deleted file mode 100644 |
... | ... |
@@ -1,67 +0,0 @@ |
1 |
-/* BraIA64.c -- Converter for IA-64 code |
|
2 |
-2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#include "Bra.h" |
|
5 |
- |
|
6 |
-static const Byte kBranchTable[32] = |
|
7 |
-{ |
|
8 |
- 0, 0, 0, 0, 0, 0, 0, 0, |
|
9 |
- 0, 0, 0, 0, 0, 0, 0, 0, |
|
10 |
- 4, 4, 6, 6, 0, 0, 7, 7, |
|
11 |
- 4, 4, 0, 0, 4, 4, 0, 0 |
|
12 |
-}; |
|
13 |
- |
|
14 |
-SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) |
|
15 |
-{ |
|
16 |
- SizeT i; |
|
17 |
- if (size < 16) |
|
18 |
- return 0; |
|
19 |
- size -= 16; |
|
20 |
- for (i = 0; i <= size; i += 16) |
|
21 |
- { |
|
22 |
- UInt32 instrTemplate = data[i] & 0x1F; |
|
23 |
- UInt32 mask = kBranchTable[instrTemplate]; |
|
24 |
- UInt32 bitPos = 5; |
|
25 |
- int slot; |
|
26 |
- for (slot = 0; slot < 3; slot++, bitPos += 41) |
|
27 |
- { |
|
28 |
- UInt32 bytePos, bitRes; |
|
29 |
- UInt64 instruction, instNorm; |
|
30 |
- int j; |
|
31 |
- if (((mask >> slot) & 1) == 0) |
|
32 |
- continue; |
|
33 |
- bytePos = (bitPos >> 3); |
|
34 |
- bitRes = bitPos & 0x7; |
|
35 |
- instruction = 0; |
|
36 |
- for (j = 0; j < 6; j++) |
|
37 |
- instruction += (UInt64)data[i + j + bytePos] << (8 * j); |
|
38 |
- |
|
39 |
- instNorm = instruction >> bitRes; |
|
40 |
- if (((instNorm >> 37) & 0xF) == 0x5 && ((instNorm >> 9) & 0x7) == 0) |
|
41 |
- { |
|
42 |
- UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF); |
|
43 |
- UInt32 dest; |
|
44 |
- src |= ((UInt32)(instNorm >> 36) & 1) << 20; |
|
45 |
- |
|
46 |
- src <<= 4; |
|
47 |
- |
|
48 |
- if (encoding) |
|
49 |
- dest = ip + (UInt32)i + src; |
|
50 |
- else |
|
51 |
- dest = src - (ip + (UInt32)i); |
|
52 |
- |
|
53 |
- dest >>= 4; |
|
54 |
- |
|
55 |
- instNorm &= ~((UInt64)(0x8FFFFF) << 13); |
|
56 |
- instNorm |= ((UInt64)(dest & 0xFFFFF) << 13); |
|
57 |
- instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20)); |
|
58 |
- |
|
59 |
- instruction &= (1 << bitRes) - 1; |
|
60 |
- instruction |= (instNorm << bitRes); |
|
61 |
- for (j = 0; j < 6; j++) |
|
62 |
- data[i + j + bytePos] = (Byte)(instruction >> (8 * j)); |
|
63 |
- } |
|
64 |
- } |
|
65 |
- } |
|
66 |
- return i; |
|
67 |
-} |
... | ... |
@@ -1,69 +1,37 @@ |
1 |
-/* CpuArch.h |
|
2 |
-2008-08-05 |
|
3 |
-Igor Pavlov |
|
4 |
-Public domain */ |
|
5 |
- |
|
6 |
-#ifndef __CPUARCH_H |
|
7 |
-#define __CPUARCH_H |
|
8 |
- |
|
9 |
-/* |
|
10 |
-LITTLE_ENDIAN_UNALIGN means: |
|
11 |
- 1) CPU is LITTLE_ENDIAN |
|
12 |
- 2) it's allowed to make unaligned memory accesses |
|
13 |
-if LITTLE_ENDIAN_UNALIGN is not defined, it means that we don't know |
|
14 |
-about these properties of platform. |
|
15 |
-*/ |
|
16 |
- |
|
17 |
-#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__) |
|
18 |
-#define LITTLE_ENDIAN_UNALIGN |
|
19 |
-#endif |
|
20 |
- |
|
21 |
-#ifdef LITTLE_ENDIAN_UNALIGN |
|
22 |
- |
|
23 |
-#define GetUi16(p) (*(const UInt16 *)(p)) |
|
24 |
-#define GetUi32(p) (*(const UInt32 *)(p)) |
|
25 |
-#define GetUi64(p) (*(const UInt64 *)(p)) |
|
26 |
-#define SetUi32(p, d) *(UInt32 *)(p) = (d); |
|
27 |
- |
|
28 |
-#else |
|
29 |
- |
|
30 |
-#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8)) |
|
31 |
- |
|
32 |
-#define GetUi32(p) ( \ |
|
33 |
- ((const Byte *)(p))[0] | \ |
|
34 |
- ((UInt32)((const Byte *)(p))[1] << 8) | \ |
|
35 |
- ((UInt32)((const Byte *)(p))[2] << 16) | \ |
|
36 |
- ((UInt32)((const Byte *)(p))[3] << 24)) |
|
37 |
- |
|
38 |
-#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) |
|
39 |
- |
|
40 |
-#define SetUi32(p, d) { UInt32 _x_ = (d); \ |
|
41 |
- ((Byte *)(p))[0] = (Byte)_x_; \ |
|
42 |
- ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \ |
|
43 |
- ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \ |
|
44 |
- ((Byte *)(p))[3] = (Byte)(_x_ >> 24); } |
|
45 |
- |
|
46 |
-#endif |
|
47 |
- |
|
48 |
-#if defined(LITTLE_ENDIAN_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300) |
|
49 |
- |
|
50 |
-#pragma intrinsic(_byteswap_ulong) |
|
51 |
-#pragma intrinsic(_byteswap_uint64) |
|
52 |
-#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p)) |
|
53 |
-#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p)) |
|
54 |
- |
|
55 |
-#else |
|
56 |
- |
|
57 |
-#define GetBe32(p) ( \ |
|
58 |
- ((UInt32)((const Byte *)(p))[0] << 24) | \ |
|
59 |
- ((UInt32)((const Byte *)(p))[1] << 16) | \ |
|
60 |
- ((UInt32)((const Byte *)(p))[2] << 8) | \ |
|
61 |
- ((const Byte *)(p))[3] ) |
|
62 |
- |
|
63 |
-#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) |
|
64 |
- |
|
65 |
-#endif |
|
66 |
- |
|
67 |
-#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1]) |
|
68 |
- |
|
69 |
-#endif |
|
1 |
+/* CpuArch.h -- CPU specific code |
|
2 |
+2010-10-26: Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#ifndef __CPU_ARCH_H |
|
5 |
+#define __CPU_ARCH_H |
|
6 |
+ |
|
7 |
+#include "Types.h" |
|
8 |
+#include "others.h" |
|
9 |
+ |
|
10 |
+EXTERN_C_BEGIN |
|
11 |
+ |
|
12 |
+/* |
|
13 |
+MY_CPU_LE means that CPU is LITTLE ENDIAN. |
|
14 |
+If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE ENDIAN). |
|
15 |
+ |
|
16 |
+MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses. |
|
17 |
+If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform. |
|
18 |
+*/ |
|
19 |
+ |
|
20 |
+#define GetUi16(p) (cli_readint16(p)) |
|
21 |
+#define GetUi32(p) (cli_readint32(p)) |
|
22 |
+ |
|
23 |
+#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) |
|
24 |
+ |
|
25 |
+#define SetUi16(p, d) { UInt32 _x_ = (d); \ |
|
26 |
+ ((Byte *)(p))[0] = (Byte)_x_; \ |
|
27 |
+ ((Byte *)(p))[1] = (Byte)(_x_ >> 8); } |
|
28 |
+ |
|
29 |
+#define SetUi32(p, d) (cli_writeint32(p, d)) |
|
30 |
+ |
|
31 |
+#define SetUi64(p, d) { UInt64 _x64_ = (d); \ |
|
32 |
+ SetUi32(p, (UInt32)_x64_); \ |
|
33 |
+ SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); } |
|
34 |
+ |
|
35 |
+EXTERN_C_END |
|
36 |
+ |
|
37 |
+#endif |
70 | 38 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,356 @@ |
0 |
+/* Lzma2Dec.c -- LZMA2 Decoder |
|
1 |
+2009-05-03 : Igor Pavlov : Public domain */ |
|
2 |
+ |
|
3 |
+/* #define SHOW_DEBUG_INFO */ |
|
4 |
+ |
|
5 |
+#ifdef SHOW_DEBUG_INFO |
|
6 |
+#include <stdio.h> |
|
7 |
+#endif |
|
8 |
+ |
|
9 |
+#include <string.h> |
|
10 |
+ |
|
11 |
+#include "Lzma2Dec.h" |
|
12 |
+ |
|
13 |
+/* |
|
14 |
+00000000 - EOS |
|
15 |
+00000001 U U - Uncompressed Reset Dic |
|
16 |
+00000010 U U - Uncompressed No Reset |
|
17 |
+100uuuuu U U P P - LZMA no reset |
|
18 |
+101uuuuu U U P P - LZMA reset state |
|
19 |
+110uuuuu U U P P S - LZMA reset state + new prop |
|
20 |
+111uuuuu U U P P S - LZMA reset state + new prop + reset dic |
|
21 |
+ |
|
22 |
+ u, U - Unpack Size |
|
23 |
+ P - Pack Size |
|
24 |
+ S - Props |
|
25 |
+*/ |
|
26 |
+ |
|
27 |
+#define LZMA2_CONTROL_LZMA (1 << 7) |
|
28 |
+#define LZMA2_CONTROL_COPY_NO_RESET 2 |
|
29 |
+#define LZMA2_CONTROL_COPY_RESET_DIC 1 |
|
30 |
+#define LZMA2_CONTROL_EOF 0 |
|
31 |
+ |
|
32 |
+#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0) |
|
33 |
+ |
|
34 |
+#define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3) |
|
35 |
+#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2) |
|
36 |
+ |
|
37 |
+#define LZMA2_LCLP_MAX 4 |
|
38 |
+#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11)) |
|
39 |
+ |
|
40 |
+#ifdef SHOW_DEBUG_INFO |
|
41 |
+#define PRF(x) x |
|
42 |
+#else |
|
43 |
+#define PRF(x) |
|
44 |
+#endif |
|
45 |
+ |
|
46 |
+typedef enum |
|
47 |
+{ |
|
48 |
+ LZMA2_STATE_CONTROL, |
|
49 |
+ LZMA2_STATE_UNPACK0, |
|
50 |
+ LZMA2_STATE_UNPACK1, |
|
51 |
+ LZMA2_STATE_PACK0, |
|
52 |
+ LZMA2_STATE_PACK1, |
|
53 |
+ LZMA2_STATE_PROP, |
|
54 |
+ LZMA2_STATE_DATA, |
|
55 |
+ LZMA2_STATE_DATA_CONT, |
|
56 |
+ LZMA2_STATE_FINISHED, |
|
57 |
+ LZMA2_STATE_ERROR |
|
58 |
+} ELzma2State; |
|
59 |
+ |
|
60 |
+static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props) |
|
61 |
+{ |
|
62 |
+ UInt32 dicSize; |
|
63 |
+ if (prop > 40) |
|
64 |
+ return SZ_ERROR_UNSUPPORTED; |
|
65 |
+ dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop); |
|
66 |
+ props[0] = (Byte)LZMA2_LCLP_MAX; |
|
67 |
+ props[1] = (Byte)(dicSize); |
|
68 |
+ props[2] = (Byte)(dicSize >> 8); |
|
69 |
+ props[3] = (Byte)(dicSize >> 16); |
|
70 |
+ props[4] = (Byte)(dicSize >> 24); |
|
71 |
+ return SZ_OK; |
|
72 |
+} |
|
73 |
+ |
|
74 |
+SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc) |
|
75 |
+{ |
|
76 |
+ Byte props[LZMA_PROPS_SIZE]; |
|
77 |
+ RINOK(Lzma2Dec_GetOldProps(prop, props)); |
|
78 |
+ return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc); |
|
79 |
+} |
|
80 |
+ |
|
81 |
+SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc) |
|
82 |
+{ |
|
83 |
+ Byte props[LZMA_PROPS_SIZE]; |
|
84 |
+ RINOK(Lzma2Dec_GetOldProps(prop, props)); |
|
85 |
+ return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc); |
|
86 |
+} |
|
87 |
+ |
|
88 |
+void Lzma2Dec_Init(CLzma2Dec *p) |
|
89 |
+{ |
|
90 |
+ p->state = LZMA2_STATE_CONTROL; |
|
91 |
+ p->needInitDic = True; |
|
92 |
+ p->needInitState = True; |
|
93 |
+ p->needInitProp = True; |
|
94 |
+ LzmaDec_Init(&p->decoder); |
|
95 |
+} |
|
96 |
+ |
|
97 |
+static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b) |
|
98 |
+{ |
|
99 |
+ switch(p->state) |
|
100 |
+ { |
|
101 |
+ case LZMA2_STATE_CONTROL: |
|
102 |
+ p->control = b; |
|
103 |
+ PRF(printf("\n %4X ", p->decoder.dicPos)); |
|
104 |
+ PRF(printf(" %2X", b)); |
|
105 |
+ if (p->control == 0) |
|
106 |
+ return LZMA2_STATE_FINISHED; |
|
107 |
+ if (LZMA2_IS_UNCOMPRESSED_STATE(p)) |
|
108 |
+ { |
|
109 |
+ if ((p->control & 0x7F) > 2) |
|
110 |
+ return LZMA2_STATE_ERROR; |
|
111 |
+ p->unpackSize = 0; |
|
112 |
+ } |
|
113 |
+ else |
|
114 |
+ p->unpackSize = (UInt32)(p->control & 0x1F) << 16; |
|
115 |
+ return LZMA2_STATE_UNPACK0; |
|
116 |
+ |
|
117 |
+ case LZMA2_STATE_UNPACK0: |
|
118 |
+ p->unpackSize |= (UInt32)b << 8; |
|
119 |
+ return LZMA2_STATE_UNPACK1; |
|
120 |
+ |
|
121 |
+ case LZMA2_STATE_UNPACK1: |
|
122 |
+ p->unpackSize |= (UInt32)b; |
|
123 |
+ p->unpackSize++; |
|
124 |
+ PRF(printf(" %8d", p->unpackSize)); |
|
125 |
+ return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0; |
|
126 |
+ |
|
127 |
+ case LZMA2_STATE_PACK0: |
|
128 |
+ p->packSize = (UInt32)b << 8; |
|
129 |
+ return LZMA2_STATE_PACK1; |
|
130 |
+ |
|
131 |
+ case LZMA2_STATE_PACK1: |
|
132 |
+ p->packSize |= (UInt32)b; |
|
133 |
+ p->packSize++; |
|
134 |
+ PRF(printf(" %8d", p->packSize)); |
|
135 |
+ return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP: |
|
136 |
+ (p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA); |
|
137 |
+ |
|
138 |
+ case LZMA2_STATE_PROP: |
|
139 |
+ { |
|
140 |
+ int lc, lp; |
|
141 |
+ if (b >= (9 * 5 * 5)) |
|
142 |
+ return LZMA2_STATE_ERROR; |
|
143 |
+ lc = b % 9; |
|
144 |
+ b /= 9; |
|
145 |
+ p->decoder.prop.pb = b / 5; |
|
146 |
+ lp = b % 5; |
|
147 |
+ if (lc + lp > LZMA2_LCLP_MAX) |
|
148 |
+ return LZMA2_STATE_ERROR; |
|
149 |
+ p->decoder.prop.lc = lc; |
|
150 |
+ p->decoder.prop.lp = lp; |
|
151 |
+ p->needInitProp = False; |
|
152 |
+ return LZMA2_STATE_DATA; |
|
153 |
+ } |
|
154 |
+ } |
|
155 |
+ return LZMA2_STATE_ERROR; |
|
156 |
+} |
|
157 |
+ |
|
158 |
+static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size) |
|
159 |
+{ |
|
160 |
+ memcpy(p->dic + p->dicPos, src, size); |
|
161 |
+ p->dicPos += size; |
|
162 |
+ if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size) |
|
163 |
+ p->checkDicSize = p->prop.dicSize; |
|
164 |
+ p->processedPos += (UInt32)size; |
|
165 |
+} |
|
166 |
+ |
|
167 |
+void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState); |
|
168 |
+ |
|
169 |
+SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, |
|
170 |
+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) |
|
171 |
+{ |
|
172 |
+ SizeT inSize = *srcLen; |
|
173 |
+ *srcLen = 0; |
|
174 |
+ *status = LZMA_STATUS_NOT_SPECIFIED; |
|
175 |
+ |
|
176 |
+ while (p->state != LZMA2_STATE_FINISHED) |
|
177 |
+ { |
|
178 |
+ SizeT dicPos = p->decoder.dicPos; |
|
179 |
+ if (p->state == LZMA2_STATE_ERROR) |
|
180 |
+ return SZ_ERROR_DATA; |
|
181 |
+ if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY) |
|
182 |
+ { |
|
183 |
+ *status = LZMA_STATUS_NOT_FINISHED; |
|
184 |
+ return SZ_OK; |
|
185 |
+ } |
|
186 |
+ if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) |
|
187 |
+ { |
|
188 |
+ if (*srcLen == inSize) |
|
189 |
+ { |
|
190 |
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT; |
|
191 |
+ return SZ_OK; |
|
192 |
+ } |
|
193 |
+ (*srcLen)++; |
|
194 |
+ p->state = Lzma2Dec_UpdateState(p, *src++); |
|
195 |
+ continue; |
|
196 |
+ } |
|
197 |
+ { |
|
198 |
+ SizeT destSizeCur = dicLimit - dicPos; |
|
199 |
+ SizeT srcSizeCur = inSize - *srcLen; |
|
200 |
+ ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY; |
|
201 |
+ |
|
202 |
+ if (p->unpackSize <= destSizeCur) |
|
203 |
+ { |
|
204 |
+ destSizeCur = (SizeT)p->unpackSize; |
|
205 |
+ curFinishMode = LZMA_FINISH_END; |
|
206 |
+ } |
|
207 |
+ |
|
208 |
+ if (LZMA2_IS_UNCOMPRESSED_STATE(p)) |
|
209 |
+ { |
|
210 |
+ if (*srcLen == inSize) |
|
211 |
+ { |
|
212 |
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT; |
|
213 |
+ return SZ_OK; |
|
214 |
+ } |
|
215 |
+ |
|
216 |
+ if (p->state == LZMA2_STATE_DATA) |
|
217 |
+ { |
|
218 |
+ Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC); |
|
219 |
+ if (initDic) |
|
220 |
+ p->needInitProp = p->needInitState = True; |
|
221 |
+ else if (p->needInitDic) |
|
222 |
+ return SZ_ERROR_DATA; |
|
223 |
+ p->needInitDic = False; |
|
224 |
+ LzmaDec_InitDicAndState(&p->decoder, initDic, False); |
|
225 |
+ } |
|
226 |
+ |
|
227 |
+ if (srcSizeCur > destSizeCur) |
|
228 |
+ srcSizeCur = destSizeCur; |
|
229 |
+ |
|
230 |
+ if (srcSizeCur == 0) |
|
231 |
+ return SZ_ERROR_DATA; |
|
232 |
+ |
|
233 |
+ LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur); |
|
234 |
+ |
|
235 |
+ src += srcSizeCur; |
|
236 |
+ *srcLen += srcSizeCur; |
|
237 |
+ p->unpackSize -= (UInt32)srcSizeCur; |
|
238 |
+ p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT; |
|
239 |
+ } |
|
240 |
+ else |
|
241 |
+ { |
|
242 |
+ SizeT outSizeProcessed; |
|
243 |
+ SRes res; |
|
244 |
+ |
|
245 |
+ if (p->state == LZMA2_STATE_DATA) |
|
246 |
+ { |
|
247 |
+ int mode = LZMA2_GET_LZMA_MODE(p); |
|
248 |
+ Bool initDic = (mode == 3); |
|
249 |
+ Bool initState = (mode > 0); |
|
250 |
+ if ((!initDic && p->needInitDic) || (!initState && p->needInitState)) |
|
251 |
+ return SZ_ERROR_DATA; |
|
252 |
+ |
|
253 |
+ LzmaDec_InitDicAndState(&p->decoder, initDic, initState); |
|
254 |
+ p->needInitDic = False; |
|
255 |
+ p->needInitState = False; |
|
256 |
+ p->state = LZMA2_STATE_DATA_CONT; |
|
257 |
+ } |
|
258 |
+ if (srcSizeCur > p->packSize) |
|
259 |
+ srcSizeCur = (SizeT)p->packSize; |
|
260 |
+ |
|
261 |
+ res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status); |
|
262 |
+ |
|
263 |
+ src += srcSizeCur; |
|
264 |
+ *srcLen += srcSizeCur; |
|
265 |
+ p->packSize -= (UInt32)srcSizeCur; |
|
266 |
+ |
|
267 |
+ outSizeProcessed = p->decoder.dicPos - dicPos; |
|
268 |
+ p->unpackSize -= (UInt32)outSizeProcessed; |
|
269 |
+ |
|
270 |
+ RINOK(res); |
|
271 |
+ if (*status == LZMA_STATUS_NEEDS_MORE_INPUT) |
|
272 |
+ return res; |
|
273 |
+ |
|
274 |
+ if (srcSizeCur == 0 && outSizeProcessed == 0) |
|
275 |
+ { |
|
276 |
+ if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK || |
|
277 |
+ p->unpackSize != 0 || p->packSize != 0) |
|
278 |
+ return SZ_ERROR_DATA; |
|
279 |
+ p->state = LZMA2_STATE_CONTROL; |
|
280 |
+ } |
|
281 |
+ if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) |
|
282 |
+ *status = LZMA_STATUS_NOT_FINISHED; |
|
283 |
+ } |
|
284 |
+ } |
|
285 |
+ } |
|
286 |
+ *status = LZMA_STATUS_FINISHED_WITH_MARK; |
|
287 |
+ return SZ_OK; |
|
288 |
+} |
|
289 |
+ |
|
290 |
+SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) |
|
291 |
+{ |
|
292 |
+ SizeT outSize = *destLen, inSize = *srcLen; |
|
293 |
+ *srcLen = *destLen = 0; |
|
294 |
+ for (;;) |
|
295 |
+ { |
|
296 |
+ SizeT srcSizeCur = inSize, outSizeCur, dicPos; |
|
297 |
+ ELzmaFinishMode curFinishMode; |
|
298 |
+ SRes res; |
|
299 |
+ if (p->decoder.dicPos == p->decoder.dicBufSize) |
|
300 |
+ p->decoder.dicPos = 0; |
|
301 |
+ dicPos = p->decoder.dicPos; |
|
302 |
+ if (outSize > p->decoder.dicBufSize - dicPos) |
|
303 |
+ { |
|
304 |
+ outSizeCur = p->decoder.dicBufSize; |
|
305 |
+ curFinishMode = LZMA_FINISH_ANY; |
|
306 |
+ } |
|
307 |
+ else |
|
308 |
+ { |
|
309 |
+ outSizeCur = dicPos + outSize; |
|
310 |
+ curFinishMode = finishMode; |
|
311 |
+ } |
|
312 |
+ |
|
313 |
+ res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status); |
|
314 |
+ src += srcSizeCur; |
|
315 |
+ inSize -= srcSizeCur; |
|
316 |
+ *srcLen += srcSizeCur; |
|
317 |
+ outSizeCur = p->decoder.dicPos - dicPos; |
|
318 |
+ memcpy(dest, p->decoder.dic + dicPos, outSizeCur); |
|
319 |
+ dest += outSizeCur; |
|
320 |
+ outSize -= outSizeCur; |
|
321 |
+ *destLen += outSizeCur; |
|
322 |
+ if (res != 0) |
|
323 |
+ return res; |
|
324 |
+ if (outSizeCur == 0 || outSize == 0) |
|
325 |
+ return SZ_OK; |
|
326 |
+ } |
|
327 |
+} |
|
328 |
+ |
|
329 |
+SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, |
|
330 |
+ Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc) |
|
331 |
+{ |
|
332 |
+ CLzma2Dec decoder; |
|
333 |
+ SRes res; |
|
334 |
+ SizeT outSize = *destLen, inSize = *srcLen; |
|
335 |
+ Byte props[LZMA_PROPS_SIZE]; |
|
336 |
+ |
|
337 |
+ Lzma2Dec_Construct(&decoder); |
|
338 |
+ |
|
339 |
+ *destLen = *srcLen = 0; |
|
340 |
+ *status = LZMA_STATUS_NOT_SPECIFIED; |
|
341 |
+ decoder.decoder.dic = dest; |
|
342 |
+ decoder.decoder.dicBufSize = outSize; |
|
343 |
+ |
|
344 |
+ RINOK(Lzma2Dec_GetOldProps(prop, props)); |
|
345 |
+ RINOK(LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc)); |
|
346 |
+ |
|
347 |
+ *srcLen = inSize; |
|
348 |
+ res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status); |
|
349 |
+ *destLen = decoder.decoder.dicPos; |
|
350 |
+ if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) |
|
351 |
+ res = SZ_ERROR_INPUT_EOF; |
|
352 |
+ |
|
353 |
+ LzmaDec_FreeProbs(&decoder.decoder, alloc); |
|
354 |
+ return res; |
|
355 |
+} |
0 | 356 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,84 @@ |
0 |
+/* Lzma2Dec.h -- LZMA2 Decoder |
|
1 |
+2009-05-03 : Igor Pavlov : Public domain */ |
|
2 |
+ |
|
3 |
+#ifndef __LZMA2_DEC_H |
|
4 |
+#define __LZMA2_DEC_H |
|
5 |
+ |
|
6 |
+#include "LzmaDec.h" |
|
7 |
+ |
|
8 |
+#ifdef __cplusplus |
|
9 |
+extern "C" { |
|
10 |
+#endif |
|
11 |
+ |
|
12 |
+/* ---------- State Interface ---------- */ |
|
13 |
+ |
|
14 |
+typedef struct |
|
15 |
+{ |
|
16 |
+ CLzmaDec decoder; |
|
17 |
+ UInt32 packSize; |
|
18 |
+ UInt32 unpackSize; |
|
19 |
+ int state; |
|
20 |
+ Byte control; |
|
21 |
+ Bool needInitDic; |
|
22 |
+ Bool needInitState; |
|
23 |
+ Bool needInitProp; |
|
24 |
+} CLzma2Dec; |
|
25 |
+ |
|
26 |
+#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder) |
|
27 |
+#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc); |
|
28 |
+#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc); |
|
29 |
+ |
|
30 |
+SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc); |
|
31 |
+SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc); |
|
32 |
+void Lzma2Dec_Init(CLzma2Dec *p); |
|
33 |
+ |
|
34 |
+ |
|
35 |
+/* |
|
36 |
+finishMode: |
|
37 |
+ It has meaning only if the decoding reaches output limit (*destLen or dicLimit). |
|
38 |
+ LZMA_FINISH_ANY - use smallest number of input bytes |
|
39 |
+ LZMA_FINISH_END - read EndOfStream marker after decoding |
|
40 |
+ |
|
41 |
+Returns: |
|
42 |
+ SZ_OK |
|
43 |
+ status: |
|
44 |
+ LZMA_STATUS_FINISHED_WITH_MARK |
|
45 |
+ LZMA_STATUS_NOT_FINISHED |
|
46 |
+ LZMA_STATUS_NEEDS_MORE_INPUT |
|
47 |
+ SZ_ERROR_DATA - Data error |
|
48 |
+*/ |
|
49 |
+ |
|
50 |
+SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, |
|
51 |
+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); |
|
52 |
+ |
|
53 |
+SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, |
|
54 |
+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); |
|
55 |
+ |
|
56 |
+ |
|
57 |
+/* ---------- One Call Interface ---------- */ |
|
58 |
+ |
|
59 |
+/* |
|
60 |
+finishMode: |
|
61 |
+ It has meaning only if the decoding reaches output limit (*destLen). |
|
62 |
+ LZMA_FINISH_ANY - use smallest number of input bytes |
|
63 |
+ LZMA_FINISH_END - read EndOfStream marker after decoding |
|
64 |
+ |
|
65 |
+Returns: |
|
66 |
+ SZ_OK |
|
67 |
+ status: |
|
68 |
+ LZMA_STATUS_FINISHED_WITH_MARK |
|
69 |
+ LZMA_STATUS_NOT_FINISHED |
|
70 |
+ SZ_ERROR_DATA - Data error |
|
71 |
+ SZ_ERROR_MEM - Memory allocation error |
|
72 |
+ SZ_ERROR_UNSUPPORTED - Unsupported properties |
|
73 |
+ SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). |
|
74 |
+*/ |
|
75 |
+ |
|
76 |
+SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, |
|
77 |
+ Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc); |
|
78 |
+ |
|
79 |
+#ifdef __cplusplus |
|
80 |
+} |
|
81 |
+#endif |
|
82 |
+ |
|
83 |
+#endif |
... | ... |
@@ -1,1007 +1,999 @@ |
1 |
-/* LzmaDec.c -- LZMA Decoder |
|
2 |
-2008-11-06 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#include "LzmaDec.h" |
|
5 |
- |
|
6 |
-#include <string.h> |
|
7 |
- |
|
8 |
-#define kNumTopBits 24 |
|
9 |
-#define kTopValue ((UInt32)1 << kNumTopBits) |
|
10 |
- |
|
11 |
-#define kNumBitModelTotalBits 11 |
|
12 |
-#define kBitModelTotal (1 << kNumBitModelTotalBits) |
|
13 |
-#define kNumMoveBits 5 |
|
14 |
- |
|
15 |
-#define RC_INIT_SIZE 5 |
|
16 |
- |
|
17 |
-#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } |
|
18 |
- |
|
19 |
-#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) |
|
20 |
-#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); |
|
21 |
-#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); |
|
22 |
-#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ |
|
23 |
- { UPDATE_0(p); i = (i + i); A0; } else \ |
|
24 |
- { UPDATE_1(p); i = (i + i) + 1; A1; } |
|
25 |
-#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) |
|
26 |
- |
|
27 |
-#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } |
|
28 |
-#define TREE_DECODE(probs, limit, i) \ |
|
29 |
- { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } |
|
30 |
- |
|
31 |
-/* #define _LZMA_SIZE_OPT */ |
|
32 |
- |
|
33 |
-#ifdef _LZMA_SIZE_OPT |
|
34 |
-#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) |
|
35 |
-#else |
|
36 |
-#define TREE_6_DECODE(probs, i) \ |
|
37 |
- { i = 1; \ |
|
38 |
- TREE_GET_BIT(probs, i); \ |
|
39 |
- TREE_GET_BIT(probs, i); \ |
|
40 |
- TREE_GET_BIT(probs, i); \ |
|
41 |
- TREE_GET_BIT(probs, i); \ |
|
42 |
- TREE_GET_BIT(probs, i); \ |
|
43 |
- TREE_GET_BIT(probs, i); \ |
|
44 |
- i -= 0x40; } |
|
45 |
-#endif |
|
46 |
- |
|
47 |
-#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } |
|
48 |
- |
|
49 |
-#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) |
|
50 |
-#define UPDATE_0_CHECK range = bound; |
|
51 |
-#define UPDATE_1_CHECK range -= bound; code -= bound; |
|
52 |
-#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ |
|
53 |
- { UPDATE_0_CHECK; i = (i + i); A0; } else \ |
|
54 |
- { UPDATE_1_CHECK; i = (i + i) + 1; A1; } |
|
55 |
-#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) |
|
56 |
-#define TREE_DECODE_CHECK(probs, limit, i) \ |
|
57 |
- { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } |
|
58 |
- |
|
59 |
- |
|
60 |
-#define kNumPosBitsMax 4 |
|
61 |
-#define kNumPosStatesMax (1 << kNumPosBitsMax) |
|
62 |
- |
|
63 |
-#define kLenNumLowBits 3 |
|
64 |
-#define kLenNumLowSymbols (1 << kLenNumLowBits) |
|
65 |
-#define kLenNumMidBits 3 |
|
66 |
-#define kLenNumMidSymbols (1 << kLenNumMidBits) |
|
67 |
-#define kLenNumHighBits 8 |
|
68 |
-#define kLenNumHighSymbols (1 << kLenNumHighBits) |
|
69 |
- |
|
70 |
-#define LenChoice 0 |
|
71 |
-#define LenChoice2 (LenChoice + 1) |
|
72 |
-#define LenLow (LenChoice2 + 1) |
|
73 |
-#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) |
|
74 |
-#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) |
|
75 |
-#define kNumLenProbs (LenHigh + kLenNumHighSymbols) |
|
76 |
- |
|
77 |
- |
|
78 |
-#define kNumStates 12 |
|
79 |
-#define kNumLitStates 7 |
|
80 |
- |
|
81 |
-#define kStartPosModelIndex 4 |
|
82 |
-#define kEndPosModelIndex 14 |
|
83 |
-#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) |
|
84 |
- |
|
85 |
-#define kNumPosSlotBits 6 |
|
86 |
-#define kNumLenToPosStates 4 |
|
87 |
- |
|
88 |
-#define kNumAlignBits 4 |
|
89 |
-#define kAlignTableSize (1 << kNumAlignBits) |
|
90 |
- |
|
91 |
-#define kMatchMinLen 2 |
|
92 |
-#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) |
|
93 |
- |
|
94 |
-#define IsMatch 0 |
|
95 |
-#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) |
|
96 |
-#define IsRepG0 (IsRep + kNumStates) |
|
97 |
-#define IsRepG1 (IsRepG0 + kNumStates) |
|
98 |
-#define IsRepG2 (IsRepG1 + kNumStates) |
|
99 |
-#define IsRep0Long (IsRepG2 + kNumStates) |
|
100 |
-#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) |
|
101 |
-#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) |
|
102 |
-#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) |
|
103 |
-#define LenCoder (Align + kAlignTableSize) |
|
104 |
-#define RepLenCoder (LenCoder + kNumLenProbs) |
|
105 |
-#define Literal (RepLenCoder + kNumLenProbs) |
|
106 |
- |
|
107 |
-#define LZMA_BASE_SIZE 1846 |
|
108 |
-#define LZMA_LIT_SIZE 768 |
|
109 |
- |
|
110 |
-#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) |
|
111 |
- |
|
112 |
-#if Literal != LZMA_BASE_SIZE |
|
113 |
-StopCompilingDueBUG |
|
114 |
-#endif |
|
115 |
- |
|
116 |
-static const Byte kLiteralNextStates[kNumStates * 2] = |
|
117 |
-{ |
|
118 |
- 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5, |
|
119 |
- 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10 |
|
120 |
-}; |
|
121 |
- |
|
122 |
-#define LZMA_DIC_MIN (1 << 12) |
|
123 |
- |
|
124 |
-/* First LZMA-symbol is always decoded. |
|
125 |
-And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization |
|
126 |
-Out: |
|
127 |
- Result: |
|
128 |
- SZ_OK - OK |
|
129 |
- SZ_ERROR_DATA - Error |
|
130 |
- p->remainLen: |
|
131 |
- < kMatchSpecLenStart : normal remain |
|
132 |
- = kMatchSpecLenStart : finished |
|
133 |
- = kMatchSpecLenStart + 1 : Flush marker |
|
134 |
- = kMatchSpecLenStart + 2 : State Init Marker |
|
135 |
-*/ |
|
136 |
- |
|
137 |
-static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) |
|
138 |
-{ |
|
139 |
- CLzmaProb *probs = p->probs; |
|
140 |
- |
|
141 |
- unsigned state = p->state; |
|
142 |
- UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; |
|
143 |
- unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; |
|
144 |
- unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; |
|
145 |
- unsigned lc = p->prop.lc; |
|
146 |
- |
|
147 |
- Byte *dic = p->dic; |
|
148 |
- SizeT dicBufSize = p->dicBufSize; |
|
149 |
- SizeT dicPos = p->dicPos; |
|
150 |
- |
|
151 |
- UInt32 processedPos = p->processedPos; |
|
152 |
- UInt32 checkDicSize = p->checkDicSize; |
|
153 |
- unsigned len = 0; |
|
154 |
- |
|
155 |
- const Byte *buf = p->buf; |
|
156 |
- UInt32 range = p->range; |
|
157 |
- UInt32 code = p->code; |
|
158 |
- |
|
159 |
- do |
|
160 |
- { |
|
161 |
- CLzmaProb *prob; |
|
162 |
- UInt32 bound; |
|
163 |
- unsigned ttt; |
|
164 |
- unsigned posState = processedPos & pbMask; |
|
165 |
- |
|
166 |
- prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; |
|
167 |
- IF_BIT_0(prob) |
|
168 |
- { |
|
169 |
- unsigned symbol; |
|
170 |
- UPDATE_0(prob); |
|
171 |
- prob = probs + Literal; |
|
172 |
- if (checkDicSize != 0 || processedPos != 0) |
|
173 |
- prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + |
|
174 |
- (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); |
|
175 |
- |
|
176 |
- if (state < kNumLitStates) |
|
177 |
- { |
|
178 |
- symbol = 1; |
|
179 |
- do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); |
|
180 |
- } |
|
181 |
- else |
|
182 |
- { |
|
183 |
- unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; |
|
184 |
- unsigned offs = 0x100; |
|
185 |
- symbol = 1; |
|
186 |
- do |
|
187 |
- { |
|
188 |
- unsigned bit; |
|
189 |
- CLzmaProb *probLit; |
|
190 |
- matchByte <<= 1; |
|
191 |
- bit = (matchByte & offs); |
|
192 |
- probLit = prob + offs + bit + symbol; |
|
193 |
- GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) |
|
194 |
- } |
|
195 |
- while (symbol < 0x100); |
|
196 |
- } |
|
197 |
- dic[dicPos++] = (Byte)symbol; |
|
198 |
- processedPos++; |
|
199 |
- |
|
200 |
- state = kLiteralNextStates[state]; |
|
201 |
- /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */ |
|
202 |
- continue; |
|
203 |
- } |
|
204 |
- else |
|
205 |
- { |
|
206 |
- UPDATE_1(prob); |
|
207 |
- prob = probs + IsRep + state; |
|
208 |
- IF_BIT_0(prob) |
|
209 |
- { |
|
210 |
- UPDATE_0(prob); |
|
211 |
- state += kNumStates; |
|
212 |
- prob = probs + LenCoder; |
|
213 |
- } |
|
214 |
- else |
|
215 |
- { |
|
216 |
- UPDATE_1(prob); |
|
217 |
- if (checkDicSize == 0 && processedPos == 0) |
|
218 |
- return SZ_ERROR_DATA; |
|
219 |
- prob = probs + IsRepG0 + state; |
|
220 |
- IF_BIT_0(prob) |
|
221 |
- { |
|
222 |
- UPDATE_0(prob); |
|
223 |
- prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; |
|
224 |
- IF_BIT_0(prob) |
|
225 |
- { |
|
226 |
- UPDATE_0(prob); |
|
227 |
- dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; |
|
228 |
- dicPos++; |
|
229 |
- processedPos++; |
|
230 |
- state = state < kNumLitStates ? 9 : 11; |
|
231 |
- continue; |
|
232 |
- } |
|
233 |
- UPDATE_1(prob); |
|
234 |
- } |
|
235 |
- else |
|
236 |
- { |
|
237 |
- UInt32 distance; |
|
238 |
- UPDATE_1(prob); |
|
239 |
- prob = probs + IsRepG1 + state; |
|
240 |
- IF_BIT_0(prob) |
|
241 |
- { |
|
242 |
- UPDATE_0(prob); |
|
243 |
- distance = rep1; |
|
244 |
- } |
|
245 |
- else |
|
246 |
- { |
|
247 |
- UPDATE_1(prob); |
|
248 |
- prob = probs + IsRepG2 + state; |
|
249 |
- IF_BIT_0(prob) |
|
250 |
- { |
|
251 |
- UPDATE_0(prob); |
|
252 |
- distance = rep2; |
|
253 |
- } |
|
254 |
- else |
|
255 |
- { |
|
256 |
- UPDATE_1(prob); |
|
257 |
- distance = rep3; |
|
258 |
- rep3 = rep2; |
|
259 |
- } |
|
260 |
- rep2 = rep1; |
|
261 |
- } |
|
262 |
- rep1 = rep0; |
|
263 |
- rep0 = distance; |
|
264 |
- } |
|
265 |
- state = state < kNumLitStates ? 8 : 11; |
|
266 |
- prob = probs + RepLenCoder; |
|
267 |
- } |
|
268 |
- { |
|
269 |
- unsigned limit, offset; |
|
270 |
- CLzmaProb *probLen = prob + LenChoice; |
|
271 |
- IF_BIT_0(probLen) |
|
272 |
- { |
|
273 |
- UPDATE_0(probLen); |
|
274 |
- probLen = prob + LenLow + (posState << kLenNumLowBits); |
|
275 |
- offset = 0; |
|
276 |
- limit = (1 << kLenNumLowBits); |
|
277 |
- } |
|
278 |
- else |
|
279 |
- { |
|
280 |
- UPDATE_1(probLen); |
|
281 |
- probLen = prob + LenChoice2; |
|
282 |
- IF_BIT_0(probLen) |
|
283 |
- { |
|
284 |
- UPDATE_0(probLen); |
|
285 |
- probLen = prob + LenMid + (posState << kLenNumMidBits); |
|
286 |
- offset = kLenNumLowSymbols; |
|
287 |
- limit = (1 << kLenNumMidBits); |
|
288 |
- } |
|
289 |
- else |
|
290 |
- { |
|
291 |
- UPDATE_1(probLen); |
|
292 |
- probLen = prob + LenHigh; |
|
293 |
- offset = kLenNumLowSymbols + kLenNumMidSymbols; |
|
294 |
- limit = (1 << kLenNumHighBits); |
|
295 |
- } |
|
296 |
- } |
|
297 |
- TREE_DECODE(probLen, limit, len); |
|
298 |
- len += offset; |
|
299 |
- } |
|
300 |
- |
|
301 |
- if (state >= kNumStates) |
|
302 |
- { |
|
303 |
- UInt32 distance; |
|
304 |
- prob = probs + PosSlot + |
|
305 |
- ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); |
|
306 |
- TREE_6_DECODE(prob, distance); |
|
307 |
- if (distance >= kStartPosModelIndex) |
|
308 |
- { |
|
309 |
- unsigned posSlot = (unsigned)distance; |
|
310 |
- int numDirectBits = (int)(((distance >> 1) - 1)); |
|
311 |
- distance = (2 | (distance & 1)); |
|
312 |
- if (posSlot < kEndPosModelIndex) |
|
313 |
- { |
|
314 |
- distance <<= numDirectBits; |
|
315 |
- prob = probs + SpecPos + distance - posSlot - 1; |
|
316 |
- { |
|
317 |
- UInt32 mask = 1; |
|
318 |
- unsigned i = 1; |
|
319 |
- do |
|
320 |
- { |
|
321 |
- GET_BIT2(prob + i, i, ; , distance |= mask); |
|
322 |
- mask <<= 1; |
|
323 |
- } |
|
324 |
- while (--numDirectBits != 0); |
|
325 |
- } |
|
326 |
- } |
|
327 |
- else |
|
328 |
- { |
|
329 |
- numDirectBits -= kNumAlignBits; |
|
330 |
- do |
|
331 |
- { |
|
332 |
- NORMALIZE |
|
333 |
- range >>= 1; |
|
334 |
- |
|
335 |
- { |
|
336 |
- UInt32 t; |
|
337 |
- code -= range; |
|
338 |
- t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ |
|
339 |
- distance = (distance << 1) + (t + 1); |
|
340 |
- code += range & t; |
|
341 |
- } |
|
342 |
- /* |
|
343 |
- distance <<= 1; |
|
344 |
- if (code >= range) |
|
345 |
- { |
|
346 |
- code -= range; |
|
347 |
- distance |= 1; |
|
348 |
- } |
|
349 |
- */ |
|
350 |
- } |
|
351 |
- while (--numDirectBits != 0); |
|
352 |
- prob = probs + Align; |
|
353 |
- distance <<= kNumAlignBits; |
|
354 |
- { |
|
355 |
- unsigned i = 1; |
|
356 |
- GET_BIT2(prob + i, i, ; , distance |= 1); |
|
357 |
- GET_BIT2(prob + i, i, ; , distance |= 2); |
|
358 |
- GET_BIT2(prob + i, i, ; , distance |= 4); |
|
359 |
- GET_BIT2(prob + i, i, ; , distance |= 8); |
|
360 |
- } |
|
361 |
- if (distance == (UInt32)0xFFFFFFFF) |
|
362 |
- { |
|
363 |
- len += kMatchSpecLenStart; |
|
364 |
- state -= kNumStates; |
|
365 |
- break; |
|
366 |
- } |
|
367 |
- } |
|
368 |
- } |
|
369 |
- rep3 = rep2; |
|
370 |
- rep2 = rep1; |
|
371 |
- rep1 = rep0; |
|
372 |
- rep0 = distance + 1; |
|
373 |
- if (checkDicSize == 0) |
|
374 |
- { |
|
375 |
- if (distance >= processedPos) |
|
376 |
- return SZ_ERROR_DATA; |
|
377 |
- } |
|
378 |
- else if (distance >= checkDicSize) |
|
379 |
- return SZ_ERROR_DATA; |
|
380 |
- state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; |
|
381 |
- /* state = kLiteralNextStates[state]; */ |
|
382 |
- } |
|
383 |
- |
|
384 |
- len += kMatchMinLen; |
|
385 |
- |
|
386 |
- if (limit == dicPos) |
|
387 |
- return SZ_ERROR_DATA; |
|
388 |
- { |
|
389 |
- SizeT rem = limit - dicPos; |
|
390 |
- unsigned curLen = ((rem < len) ? (unsigned)rem : len); |
|
391 |
- SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); |
|
392 |
- |
|
393 |
- processedPos += curLen; |
|
394 |
- |
|
395 |
- len -= curLen; |
|
396 |
- if (pos + curLen <= dicBufSize) |
|
397 |
- { |
|
398 |
- Byte *dest = dic + dicPos; |
|
399 |
- ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; |
|
400 |
- const Byte *lim = dest + curLen; |
|
401 |
- dicPos += curLen; |
|
402 |
- do |
|
403 |
- *(dest) = (Byte)*(dest + src); |
|
404 |
- while (++dest != lim); |
|
405 |
- } |
|
406 |
- else |
|
407 |
- { |
|
408 |
- do |
|
409 |
- { |
|
410 |
- dic[dicPos++] = dic[pos]; |
|
411 |
- if (++pos == dicBufSize) |
|
412 |
- pos = 0; |
|
413 |
- } |
|
414 |
- while (--curLen != 0); |
|
415 |
- } |
|
416 |
- } |
|
417 |
- } |
|
418 |
- } |
|
419 |
- while (dicPos < limit && buf < bufLimit); |
|
420 |
- NORMALIZE; |
|
421 |
- p->buf = buf; |
|
422 |
- p->range = range; |
|
423 |
- p->code = code; |
|
424 |
- p->remainLen = len; |
|
425 |
- p->dicPos = dicPos; |
|
426 |
- p->processedPos = processedPos; |
|
427 |
- p->reps[0] = rep0; |
|
428 |
- p->reps[1] = rep1; |
|
429 |
- p->reps[2] = rep2; |
|
430 |
- p->reps[3] = rep3; |
|
431 |
- p->state = state; |
|
432 |
- |
|
433 |
- return SZ_OK; |
|
434 |
-} |
|
435 |
- |
|
436 |
-static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) |
|
437 |
-{ |
|
438 |
- if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) |
|
439 |
- { |
|
440 |
- Byte *dic = p->dic; |
|
441 |
- SizeT dicPos = p->dicPos; |
|
442 |
- SizeT dicBufSize = p->dicBufSize; |
|
443 |
- unsigned len = p->remainLen; |
|
444 |
- UInt32 rep0 = p->reps[0]; |
|
445 |
- if (limit - dicPos < len) |
|
446 |
- len = (unsigned)(limit - dicPos); |
|
447 |
- |
|
448 |
- if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) |
|
449 |
- p->checkDicSize = p->prop.dicSize; |
|
450 |
- |
|
451 |
- p->processedPos += len; |
|
452 |
- p->remainLen -= len; |
|
453 |
- while (len-- != 0) |
|
454 |
- { |
|
455 |
- dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; |
|
456 |
- dicPos++; |
|
457 |
- } |
|
458 |
- p->dicPos = dicPos; |
|
459 |
- } |
|
460 |
-} |
|
461 |
- |
|
462 |
-static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) |
|
463 |
-{ |
|
464 |
- do |
|
465 |
- { |
|
466 |
- SizeT limit2 = limit; |
|
467 |
- if (p->checkDicSize == 0) |
|
468 |
- { |
|
469 |
- UInt32 rem = p->prop.dicSize - p->processedPos; |
|
470 |
- if (limit - p->dicPos > rem) |
|
471 |
- limit2 = p->dicPos + rem; |
|
472 |
- } |
|
473 |
- RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); |
|
474 |
- if (p->processedPos >= p->prop.dicSize) |
|
475 |
- p->checkDicSize = p->prop.dicSize; |
|
476 |
- LzmaDec_WriteRem(p, limit); |
|
477 |
- } |
|
478 |
- while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); |
|
479 |
- |
|
480 |
- if (p->remainLen > kMatchSpecLenStart) |
|
481 |
- { |
|
482 |
- p->remainLen = kMatchSpecLenStart; |
|
483 |
- } |
|
484 |
- return 0; |
|
485 |
-} |
|
486 |
- |
|
487 |
-typedef enum |
|
488 |
-{ |
|
489 |
- DUMMY_ERROR, /* unexpected end of input stream */ |
|
490 |
- DUMMY_LIT, |
|
491 |
- DUMMY_MATCH, |
|
492 |
- DUMMY_REP |
|
493 |
-} ELzmaDummy; |
|
494 |
- |
|
495 |
-static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) |
|
496 |
-{ |
|
497 |
- UInt32 range = p->range; |
|
498 |
- UInt32 code = p->code; |
|
499 |
- const Byte *bufLimit = buf + inSize; |
|
500 |
- CLzmaProb *probs = p->probs; |
|
501 |
- unsigned state = p->state; |
|
502 |
- ELzmaDummy res; |
|
503 |
- |
|
504 |
- { |
|
505 |
- CLzmaProb *prob; |
|
506 |
- UInt32 bound; |
|
507 |
- unsigned ttt; |
|
508 |
- unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); |
|
509 |
- |
|
510 |
- prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; |
|
511 |
- IF_BIT_0_CHECK(prob) |
|
512 |
- { |
|
513 |
- UPDATE_0_CHECK |
|
514 |
- |
|
515 |
- /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ |
|
516 |
- |
|
517 |
- prob = probs + Literal; |
|
518 |
- if (p->checkDicSize != 0 || p->processedPos != 0) |
|
519 |
- prob += (LZMA_LIT_SIZE * |
|
520 |
- ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + |
|
521 |
- (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); |
|
522 |
- |
|
523 |
- if (state < kNumLitStates) |
|
524 |
- { |
|
525 |
- unsigned symbol = 1; |
|
526 |
- do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); |
|
527 |
- } |
|
528 |
- else |
|
529 |
- { |
|
530 |
- unsigned matchByte = p->dic[p->dicPos - p->reps[0] + |
|
531 |
- ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; |
|
532 |
- unsigned offs = 0x100; |
|
533 |
- unsigned symbol = 1; |
|
534 |
- do |
|
535 |
- { |
|
536 |
- unsigned bit; |
|
537 |
- CLzmaProb *probLit; |
|
538 |
- matchByte <<= 1; |
|
539 |
- bit = (matchByte & offs); |
|
540 |
- probLit = prob + offs + bit + symbol; |
|
541 |
- GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) |
|
542 |
- } |
|
543 |
- while (symbol < 0x100); |
|
544 |
- } |
|
545 |
- res = DUMMY_LIT; |
|
546 |
- } |
|
547 |
- else |
|
548 |
- { |
|
549 |
- unsigned len; |
|
550 |
- UPDATE_1_CHECK; |
|
551 |
- |
|
552 |
- prob = probs + IsRep + state; |
|
553 |
- IF_BIT_0_CHECK(prob) |
|
554 |
- { |
|
555 |
- UPDATE_0_CHECK; |
|
556 |
- state = 0; |
|
557 |
- prob = probs + LenCoder; |
|
558 |
- res = DUMMY_MATCH; |
|
559 |
- } |
|
560 |
- else |
|
561 |
- { |
|
562 |
- UPDATE_1_CHECK; |
|
563 |
- res = DUMMY_REP; |
|
564 |
- prob = probs + IsRepG0 + state; |
|
565 |
- IF_BIT_0_CHECK(prob) |
|
566 |
- { |
|
567 |
- UPDATE_0_CHECK; |
|
568 |
- prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; |
|
569 |
- IF_BIT_0_CHECK(prob) |
|
570 |
- { |
|
571 |
- UPDATE_0_CHECK; |
|
572 |
- NORMALIZE_CHECK; |
|
573 |
- return DUMMY_REP; |
|
574 |
- } |
|
575 |
- else |
|
576 |
- { |
|
577 |
- UPDATE_1_CHECK; |
|
578 |
- } |
|
579 |
- } |
|
580 |
- else |
|
581 |
- { |
|
582 |
- UPDATE_1_CHECK; |
|
583 |
- prob = probs + IsRepG1 + state; |
|
584 |
- IF_BIT_0_CHECK(prob) |
|
585 |
- { |
|
586 |
- UPDATE_0_CHECK; |
|
587 |
- } |
|
588 |
- else |
|
589 |
- { |
|
590 |
- UPDATE_1_CHECK; |
|
591 |
- prob = probs + IsRepG2 + state; |
|
592 |
- IF_BIT_0_CHECK(prob) |
|
593 |
- { |
|
594 |
- UPDATE_0_CHECK; |
|
595 |
- } |
|
596 |
- else |
|
597 |
- { |
|
598 |
- UPDATE_1_CHECK; |
|
599 |
- } |
|
600 |
- } |
|
601 |
- } |
|
602 |
- state = kNumStates; |
|
603 |
- prob = probs + RepLenCoder; |
|
604 |
- } |
|
605 |
- { |
|
606 |
- unsigned limit, offset; |
|
607 |
- CLzmaProb *probLen = prob + LenChoice; |
|
608 |
- IF_BIT_0_CHECK(probLen) |
|
609 |
- { |
|
610 |
- UPDATE_0_CHECK; |
|
611 |
- probLen = prob + LenLow + (posState << kLenNumLowBits); |
|
612 |
- offset = 0; |
|
613 |
- limit = 1 << kLenNumLowBits; |
|
614 |
- } |
|
615 |
- else |
|
616 |
- { |
|
617 |
- UPDATE_1_CHECK; |
|
618 |
- probLen = prob + LenChoice2; |
|
619 |
- IF_BIT_0_CHECK(probLen) |
|
620 |
- { |
|
621 |
- UPDATE_0_CHECK; |
|
622 |
- probLen = prob + LenMid + (posState << kLenNumMidBits); |
|
623 |
- offset = kLenNumLowSymbols; |
|
624 |
- limit = 1 << kLenNumMidBits; |
|
625 |
- } |
|
626 |
- else |
|
627 |
- { |
|
628 |
- UPDATE_1_CHECK; |
|
629 |
- probLen = prob + LenHigh; |
|
630 |
- offset = kLenNumLowSymbols + kLenNumMidSymbols; |
|
631 |
- limit = 1 << kLenNumHighBits; |
|
632 |
- } |
|
633 |
- } |
|
634 |
- TREE_DECODE_CHECK(probLen, limit, len); |
|
635 |
- len += offset; |
|
636 |
- } |
|
637 |
- |
|
638 |
- if (state < 4) |
|
639 |
- { |
|
640 |
- unsigned posSlot; |
|
641 |
- prob = probs + PosSlot + |
|
642 |
- ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << |
|
643 |
- kNumPosSlotBits); |
|
644 |
- TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); |
|
645 |
- if (posSlot >= kStartPosModelIndex) |
|
646 |
- { |
|
647 |
- int numDirectBits = ((posSlot >> 1) - 1); |
|
648 |
- |
|
649 |
- /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ |
|
650 |
- |
|
651 |
- if (posSlot < kEndPosModelIndex) |
|
652 |
- { |
|
653 |
- prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; |
|
654 |
- } |
|
655 |
- else |
|
656 |
- { |
|
657 |
- numDirectBits -= kNumAlignBits; |
|
658 |
- do |
|
659 |
- { |
|
660 |
- NORMALIZE_CHECK |
|
661 |
- range >>= 1; |
|
662 |
- code -= range & (((code - range) >> 31) - 1); |
|
663 |
- /* if (code >= range) code -= range; */ |
|
664 |
- } |
|
665 |
- while (--numDirectBits != 0); |
|
666 |
- prob = probs + Align; |
|
667 |
- numDirectBits = kNumAlignBits; |
|
668 |
- } |
|
669 |
- { |
|
670 |
- unsigned i = 1; |
|
671 |
- do |
|
672 |
- { |
|
673 |
- GET_BIT_CHECK(prob + i, i); |
|
674 |
- } |
|
675 |
- while (--numDirectBits != 0); |
|
676 |
- } |
|
677 |
- } |
|
678 |
- } |
|
679 |
- } |
|
680 |
- } |
|
681 |
- NORMALIZE_CHECK; |
|
682 |
- return res; |
|
683 |
-} |
|
684 |
- |
|
685 |
- |
|
686 |
-static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) |
|
687 |
-{ |
|
688 |
- p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); |
|
689 |
- p->range = 0xFFFFFFFF; |
|
690 |
- p->needFlush = 0; |
|
691 |
-} |
|
692 |
- |
|
693 |
-void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) |
|
694 |
-{ |
|
695 |
- p->needFlush = 1; |
|
696 |
- p->remainLen = 0; |
|
697 |
- p->tempBufSize = 0; |
|
698 |
- |
|
699 |
- if (initDic) |
|
700 |
- { |
|
701 |
- p->processedPos = 0; |
|
702 |
- p->checkDicSize = 0; |
|
703 |
- p->needInitState = 1; |
|
704 |
- } |
|
705 |
- if (initState) |
|
706 |
- p->needInitState = 1; |
|
707 |
-} |
|
708 |
- |
|
709 |
-void LzmaDec_Init(CLzmaDec *p) |
|
710 |
-{ |
|
711 |
- p->dicPos = 0; |
|
712 |
- LzmaDec_InitDicAndState(p, True, True); |
|
713 |
-} |
|
714 |
- |
|
715 |
-static void LzmaDec_InitStateReal(CLzmaDec *p) |
|
716 |
-{ |
|
717 |
- UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); |
|
718 |
- UInt32 i; |
|
719 |
- CLzmaProb *probs = p->probs; |
|
720 |
- for (i = 0; i < numProbs; i++) |
|
721 |
- probs[i] = kBitModelTotal >> 1; |
|
722 |
- p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; |
|
723 |
- p->state = 0; |
|
724 |
- p->needInitState = 0; |
|
725 |
-} |
|
726 |
- |
|
727 |
-SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, |
|
728 |
- ELzmaFinishMode finishMode, ELzmaStatus *status) |
|
729 |
-{ |
|
730 |
- SizeT inSize = *srcLen; |
|
731 |
- (*srcLen) = 0; |
|
732 |
- LzmaDec_WriteRem(p, dicLimit); |
|
733 |
- |
|
734 |
- *status = LZMA_STATUS_NOT_SPECIFIED; |
|
735 |
- |
|
736 |
- while (p->remainLen != kMatchSpecLenStart) |
|
737 |
- { |
|
738 |
- int checkEndMarkNow; |
|
739 |
- |
|
740 |
- if (p->needFlush != 0) |
|
741 |
- { |
|
742 |
- for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) |
|
743 |
- p->tempBuf[p->tempBufSize++] = *src++; |
|
744 |
- if (p->tempBufSize < RC_INIT_SIZE) |
|
745 |
- { |
|
746 |
- *status = LZMA_STATUS_NEEDS_MORE_INPUT; |
|
747 |
- return SZ_OK; |
|
748 |
- } |
|
749 |
- if (p->tempBuf[0] != 0) |
|
750 |
- return SZ_ERROR_DATA; |
|
751 |
- |
|
752 |
- LzmaDec_InitRc(p, p->tempBuf); |
|
753 |
- p->tempBufSize = 0; |
|
754 |
- } |
|
755 |
- |
|
756 |
- checkEndMarkNow = 0; |
|
757 |
- if (p->dicPos >= dicLimit) |
|
758 |
- { |
|
759 |
- if (p->remainLen == 0 && p->code == 0) |
|
760 |
- { |
|
761 |
- *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; |
|
762 |
- return SZ_OK; |
|
763 |
- } |
|
764 |
- if (finishMode == LZMA_FINISH_ANY) |
|
765 |
- { |
|
766 |
- *status = LZMA_STATUS_NOT_FINISHED; |
|
767 |
- return SZ_OK; |
|
768 |
- } |
|
769 |
- if (p->remainLen != 0) |
|
770 |
- { |
|
771 |
- *status = LZMA_STATUS_NOT_FINISHED; |
|
772 |
- return SZ_ERROR_DATA; |
|
773 |
- } |
|
774 |
- checkEndMarkNow = 1; |
|
775 |
- } |
|
776 |
- |
|
777 |
- if (p->needInitState) |
|
778 |
- LzmaDec_InitStateReal(p); |
|
779 |
- |
|
780 |
- if (p->tempBufSize == 0) |
|
781 |
- { |
|
782 |
- SizeT processed; |
|
783 |
- const Byte *bufLimit; |
|
784 |
- if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) |
|
785 |
- { |
|
786 |
- int dummyRes = LzmaDec_TryDummy(p, src, inSize); |
|
787 |
- if (dummyRes == DUMMY_ERROR) |
|
788 |
- { |
|
789 |
- memcpy(p->tempBuf, src, inSize); |
|
790 |
- p->tempBufSize = (unsigned)inSize; |
|
791 |
- (*srcLen) += inSize; |
|
792 |
- *status = LZMA_STATUS_NEEDS_MORE_INPUT; |
|
793 |
- return SZ_OK; |
|
794 |
- } |
|
795 |
- if (checkEndMarkNow && dummyRes != DUMMY_MATCH) |
|
796 |
- { |
|
797 |
- *status = LZMA_STATUS_NOT_FINISHED; |
|
798 |
- return SZ_ERROR_DATA; |
|
799 |
- } |
|
800 |
- bufLimit = src; |
|
801 |
- } |
|
802 |
- else |
|
803 |
- bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; |
|
804 |
- p->buf = src; |
|
805 |
- if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) |
|
806 |
- return SZ_ERROR_DATA; |
|
807 |
- processed = (SizeT)(p->buf - src); |
|
808 |
- (*srcLen) += processed; |
|
809 |
- src += processed; |
|
810 |
- inSize -= processed; |
|
811 |
- } |
|
812 |
- else |
|
813 |
- { |
|
814 |
- unsigned rem = p->tempBufSize, lookAhead = 0; |
|
815 |
- while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) |
|
816 |
- p->tempBuf[rem++] = src[lookAhead++]; |
|
817 |
- p->tempBufSize = rem; |
|
818 |
- if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) |
|
819 |
- { |
|
820 |
- int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); |
|
821 |
- if (dummyRes == DUMMY_ERROR) |
|
822 |
- { |
|
823 |
- (*srcLen) += lookAhead; |
|
824 |
- *status = LZMA_STATUS_NEEDS_MORE_INPUT; |
|
825 |
- return SZ_OK; |
|
826 |
- } |
|
827 |
- if (checkEndMarkNow && dummyRes != DUMMY_MATCH) |
|
828 |
- { |
|
829 |
- *status = LZMA_STATUS_NOT_FINISHED; |
|
830 |
- return SZ_ERROR_DATA; |
|
831 |
- } |
|
832 |
- } |
|
833 |
- p->buf = p->tempBuf; |
|
834 |
- if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) |
|
835 |
- return SZ_ERROR_DATA; |
|
836 |
- lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); |
|
837 |
- (*srcLen) += lookAhead; |
|
838 |
- src += lookAhead; |
|
839 |
- inSize -= lookAhead; |
|
840 |
- p->tempBufSize = 0; |
|
841 |
- } |
|
842 |
- } |
|
843 |
- if (p->code == 0) |
|
844 |
- *status = LZMA_STATUS_FINISHED_WITH_MARK; |
|
845 |
- return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; |
|
846 |
-} |
|
847 |
- |
|
848 |
-SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) |
|
849 |
-{ |
|
850 |
- SizeT outSize = *destLen; |
|
851 |
- SizeT inSize = *srcLen; |
|
852 |
- *srcLen = *destLen = 0; |
|
853 |
- for (;;) |
|
854 |
- { |
|
855 |
- SizeT inSizeCur = inSize, outSizeCur, dicPos; |
|
856 |
- ELzmaFinishMode curFinishMode; |
|
857 |
- SRes res; |
|
858 |
- if (p->dicPos == p->dicBufSize) |
|
859 |
- p->dicPos = 0; |
|
860 |
- dicPos = p->dicPos; |
|
861 |
- if (outSize > p->dicBufSize - dicPos) |
|
862 |
- { |
|
863 |
- outSizeCur = p->dicBufSize; |
|
864 |
- curFinishMode = LZMA_FINISH_ANY; |
|
865 |
- } |
|
866 |
- else |
|
867 |
- { |
|
868 |
- outSizeCur = dicPos + outSize; |
|
869 |
- curFinishMode = finishMode; |
|
870 |
- } |
|
871 |
- |
|
872 |
- res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); |
|
873 |
- src += inSizeCur; |
|
874 |
- inSize -= inSizeCur; |
|
875 |
- *srcLen += inSizeCur; |
|
876 |
- outSizeCur = p->dicPos - dicPos; |
|
877 |
- memcpy(dest, p->dic + dicPos, outSizeCur); |
|
878 |
- dest += outSizeCur; |
|
879 |
- outSize -= outSizeCur; |
|
880 |
- *destLen += outSizeCur; |
|
881 |
- if (res != 0) |
|
882 |
- return res; |
|
883 |
- if (outSizeCur == 0 || outSize == 0) |
|
884 |
- return SZ_OK; |
|
885 |
- } |
|
886 |
-} |
|
887 |
- |
|
888 |
-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) |
|
889 |
-{ |
|
890 |
- alloc->Free(alloc, p->probs); |
|
891 |
- p->probs = 0; |
|
892 |
-} |
|
893 |
- |
|
894 |
-static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) |
|
895 |
-{ |
|
896 |
- alloc->Free(alloc, p->dic); |
|
897 |
- p->dic = 0; |
|
898 |
-} |
|
899 |
- |
|
900 |
-void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) |
|
901 |
-{ |
|
902 |
- LzmaDec_FreeProbs(p, alloc); |
|
903 |
- LzmaDec_FreeDict(p, alloc); |
|
904 |
-} |
|
905 |
- |
|
906 |
-SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) |
|
907 |
-{ |
|
908 |
- UInt32 dicSize; |
|
909 |
- Byte d; |
|
910 |
- |
|
911 |
- if (size < LZMA_PROPS_SIZE) |
|
912 |
- return SZ_ERROR_UNSUPPORTED; |
|
913 |
- else |
|
914 |
- dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); |
|
915 |
- |
|
916 |
- if (dicSize < LZMA_DIC_MIN) |
|
917 |
- dicSize = LZMA_DIC_MIN; |
|
918 |
- p->dicSize = dicSize; |
|
919 |
- |
|
920 |
- d = data[0]; |
|
921 |
- if (d >= (9 * 5 * 5)) |
|
922 |
- return SZ_ERROR_UNSUPPORTED; |
|
923 |
- |
|
924 |
- p->lc = d % 9; |
|
925 |
- d /= 9; |
|
926 |
- p->pb = d / 5; |
|
927 |
- p->lp = d % 5; |
|
928 |
- |
|
929 |
- return SZ_OK; |
|
930 |
-} |
|
931 |
- |
|
932 |
-static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) |
|
933 |
-{ |
|
934 |
- UInt32 numProbs = LzmaProps_GetNumProbs(propNew); |
|
935 |
- if (p->probs == 0 || numProbs != p->numProbs) |
|
936 |
- { |
|
937 |
- LzmaDec_FreeProbs(p, alloc); |
|
938 |
- p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); |
|
939 |
- p->numProbs = numProbs; |
|
940 |
- if (p->probs == 0) |
|
941 |
- return SZ_ERROR_MEM; |
|
942 |
- } |
|
943 |
- return SZ_OK; |
|
944 |
-} |
|
945 |
- |
|
946 |
-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) |
|
947 |
-{ |
|
948 |
- CLzmaProps propNew; |
|
949 |
- RINOK(LzmaProps_Decode(&propNew, props, propsSize)); |
|
950 |
- RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); |
|
951 |
- p->prop = propNew; |
|
952 |
- return SZ_OK; |
|
953 |
-} |
|
954 |
- |
|
955 |
-SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) |
|
956 |
-{ |
|
957 |
- CLzmaProps propNew; |
|
958 |
- SizeT dicBufSize; |
|
959 |
- RINOK(LzmaProps_Decode(&propNew, props, propsSize)); |
|
960 |
- RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); |
|
961 |
- dicBufSize = propNew.dicSize; |
|
962 |
- if (p->dic == 0 || dicBufSize != p->dicBufSize) |
|
963 |
- { |
|
964 |
- LzmaDec_FreeDict(p, alloc); |
|
965 |
- p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); |
|
966 |
- if (p->dic == 0) |
|
967 |
- { |
|
968 |
- LzmaDec_FreeProbs(p, alloc); |
|
969 |
- return SZ_ERROR_MEM; |
|
970 |
- } |
|
971 |
- } |
|
972 |
- p->dicBufSize = dicBufSize; |
|
973 |
- p->prop = propNew; |
|
974 |
- return SZ_OK; |
|
975 |
-} |
|
976 |
- |
|
977 |
-SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, |
|
978 |
- const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, |
|
979 |
- ELzmaStatus *status, ISzAlloc *alloc) |
|
980 |
-{ |
|
981 |
- CLzmaDec p; |
|
982 |
- SRes res; |
|
983 |
- SizeT inSize = *srcLen; |
|
984 |
- SizeT outSize = *destLen; |
|
985 |
- *srcLen = *destLen = 0; |
|
986 |
- if (inSize < RC_INIT_SIZE) |
|
987 |
- return SZ_ERROR_INPUT_EOF; |
|
988 |
- |
|
989 |
- LzmaDec_Construct(&p); |
|
990 |
- res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); |
|
991 |
- if (res != 0) |
|
992 |
- return res; |
|
993 |
- p.dic = dest; |
|
994 |
- p.dicBufSize = outSize; |
|
995 |
- |
|
996 |
- LzmaDec_Init(&p); |
|
997 |
- |
|
998 |
- *srcLen = inSize; |
|
999 |
- res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); |
|
1000 |
- |
|
1001 |
- if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) |
|
1002 |
- res = SZ_ERROR_INPUT_EOF; |
|
1003 |
- |
|
1004 |
- (*destLen) = p.dicPos; |
|
1005 |
- LzmaDec_FreeProbs(&p, alloc); |
|
1006 |
- return res; |
|
1007 |
-} |
|
1 |
+/* LzmaDec.c -- LZMA Decoder |
|
2 |
+2009-09-20 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#include "LzmaDec.h" |
|
5 |
+ |
|
6 |
+#include <string.h> |
|
7 |
+ |
|
8 |
+#define kNumTopBits 24 |
|
9 |
+#define kTopValue ((UInt32)1 << kNumTopBits) |
|
10 |
+ |
|
11 |
+#define kNumBitModelTotalBits 11 |
|
12 |
+#define kBitModelTotal (1 << kNumBitModelTotalBits) |
|
13 |
+#define kNumMoveBits 5 |
|
14 |
+ |
|
15 |
+#define RC_INIT_SIZE 5 |
|
16 |
+ |
|
17 |
+#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } |
|
18 |
+ |
|
19 |
+#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) |
|
20 |
+#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); |
|
21 |
+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); |
|
22 |
+#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ |
|
23 |
+ { UPDATE_0(p); i = (i + i); A0; } else \ |
|
24 |
+ { UPDATE_1(p); i = (i + i) + 1; A1; } |
|
25 |
+#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) |
|
26 |
+ |
|
27 |
+#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } |
|
28 |
+#define TREE_DECODE(probs, limit, i) \ |
|
29 |
+ { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } |
|
30 |
+ |
|
31 |
+/* #define _LZMA_SIZE_OPT */ |
|
32 |
+ |
|
33 |
+#ifdef _LZMA_SIZE_OPT |
|
34 |
+#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) |
|
35 |
+#else |
|
36 |
+#define TREE_6_DECODE(probs, i) \ |
|
37 |
+ { i = 1; \ |
|
38 |
+ TREE_GET_BIT(probs, i); \ |
|
39 |
+ TREE_GET_BIT(probs, i); \ |
|
40 |
+ TREE_GET_BIT(probs, i); \ |
|
41 |
+ TREE_GET_BIT(probs, i); \ |
|
42 |
+ TREE_GET_BIT(probs, i); \ |
|
43 |
+ TREE_GET_BIT(probs, i); \ |
|
44 |
+ i -= 0x40; } |
|
45 |
+#endif |
|
46 |
+ |
|
47 |
+#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } |
|
48 |
+ |
|
49 |
+#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) |
|
50 |
+#define UPDATE_0_CHECK range = bound; |
|
51 |
+#define UPDATE_1_CHECK range -= bound; code -= bound; |
|
52 |
+#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ |
|
53 |
+ { UPDATE_0_CHECK; i = (i + i); A0; } else \ |
|
54 |
+ { UPDATE_1_CHECK; i = (i + i) + 1; A1; } |
|
55 |
+#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) |
|
56 |
+#define TREE_DECODE_CHECK(probs, limit, i) \ |
|
57 |
+ { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } |
|
58 |
+ |
|
59 |
+ |
|
60 |
+#define kNumPosBitsMax 4 |
|
61 |
+#define kNumPosStatesMax (1 << kNumPosBitsMax) |
|
62 |
+ |
|
63 |
+#define kLenNumLowBits 3 |
|
64 |
+#define kLenNumLowSymbols (1 << kLenNumLowBits) |
|
65 |
+#define kLenNumMidBits 3 |
|
66 |
+#define kLenNumMidSymbols (1 << kLenNumMidBits) |
|
67 |
+#define kLenNumHighBits 8 |
|
68 |
+#define kLenNumHighSymbols (1 << kLenNumHighBits) |
|
69 |
+ |
|
70 |
+#define LenChoice 0 |
|
71 |
+#define LenChoice2 (LenChoice + 1) |
|
72 |
+#define LenLow (LenChoice2 + 1) |
|
73 |
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) |
|
74 |
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) |
|
75 |
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols) |
|
76 |
+ |
|
77 |
+ |
|
78 |
+#define kNumStates 12 |
|
79 |
+#define kNumLitStates 7 |
|
80 |
+ |
|
81 |
+#define kStartPosModelIndex 4 |
|
82 |
+#define kEndPosModelIndex 14 |
|
83 |
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) |
|
84 |
+ |
|
85 |
+#define kNumPosSlotBits 6 |
|
86 |
+#define kNumLenToPosStates 4 |
|
87 |
+ |
|
88 |
+#define kNumAlignBits 4 |
|
89 |
+#define kAlignTableSize (1 << kNumAlignBits) |
|
90 |
+ |
|
91 |
+#define kMatchMinLen 2 |
|
92 |
+#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) |
|
93 |
+ |
|
94 |
+#define IsMatch 0 |
|
95 |
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) |
|
96 |
+#define IsRepG0 (IsRep + kNumStates) |
|
97 |
+#define IsRepG1 (IsRepG0 + kNumStates) |
|
98 |
+#define IsRepG2 (IsRepG1 + kNumStates) |
|
99 |
+#define IsRep0Long (IsRepG2 + kNumStates) |
|
100 |
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) |
|
101 |
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) |
|
102 |
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) |
|
103 |
+#define LenCoder (Align + kAlignTableSize) |
|
104 |
+#define RepLenCoder (LenCoder + kNumLenProbs) |
|
105 |
+#define Literal (RepLenCoder + kNumLenProbs) |
|
106 |
+ |
|
107 |
+#define LZMA_BASE_SIZE 1846 |
|
108 |
+#define LZMA_LIT_SIZE 768 |
|
109 |
+ |
|
110 |
+#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) |
|
111 |
+ |
|
112 |
+#if Literal != LZMA_BASE_SIZE |
|
113 |
+StopCompilingDueBUG |
|
114 |
+#endif |
|
115 |
+ |
|
116 |
+#define LZMA_DIC_MIN (1 << 12) |
|
117 |
+ |
|
118 |
+/* First LZMA-symbol is always decoded. |
|
119 |
+And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization |
|
120 |
+Out: |
|
121 |
+ Result: |
|
122 |
+ SZ_OK - OK |
|
123 |
+ SZ_ERROR_DATA - Error |
|
124 |
+ p->remainLen: |
|
125 |
+ < kMatchSpecLenStart : normal remain |
|
126 |
+ = kMatchSpecLenStart : finished |
|
127 |
+ = kMatchSpecLenStart + 1 : Flush marker |
|
128 |
+ = kMatchSpecLenStart + 2 : State Init Marker |
|
129 |
+*/ |
|
130 |
+ |
|
131 |
+static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) |
|
132 |
+{ |
|
133 |
+ CLzmaProb *probs = p->probs; |
|
134 |
+ |
|
135 |
+ unsigned state = p->state; |
|
136 |
+ UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; |
|
137 |
+ unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; |
|
138 |
+ unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; |
|
139 |
+ unsigned lc = p->prop.lc; |
|
140 |
+ |
|
141 |
+ Byte *dic = p->dic; |
|
142 |
+ SizeT dicBufSize = p->dicBufSize; |
|
143 |
+ SizeT dicPos = p->dicPos; |
|
144 |
+ |
|
145 |
+ UInt32 processedPos = p->processedPos; |
|
146 |
+ UInt32 checkDicSize = p->checkDicSize; |
|
147 |
+ unsigned len = 0; |
|
148 |
+ |
|
149 |
+ const Byte *buf = p->buf; |
|
150 |
+ UInt32 range = p->range; |
|
151 |
+ UInt32 code = p->code; |
|
152 |
+ |
|
153 |
+ do |
|
154 |
+ { |
|
155 |
+ CLzmaProb *prob; |
|
156 |
+ UInt32 bound; |
|
157 |
+ unsigned ttt; |
|
158 |
+ unsigned posState = processedPos & pbMask; |
|
159 |
+ |
|
160 |
+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; |
|
161 |
+ IF_BIT_0(prob) |
|
162 |
+ { |
|
163 |
+ unsigned symbol; |
|
164 |
+ UPDATE_0(prob); |
|
165 |
+ prob = probs + Literal; |
|
166 |
+ if (checkDicSize != 0 || processedPos != 0) |
|
167 |
+ prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + |
|
168 |
+ (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); |
|
169 |
+ |
|
170 |
+ if (state < kNumLitStates) |
|
171 |
+ { |
|
172 |
+ state -= (state < 4) ? state : 3; |
|
173 |
+ symbol = 1; |
|
174 |
+ do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); |
|
175 |
+ } |
|
176 |
+ else |
|
177 |
+ { |
|
178 |
+ unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; |
|
179 |
+ unsigned offs = 0x100; |
|
180 |
+ state -= (state < 10) ? 3 : 6; |
|
181 |
+ symbol = 1; |
|
182 |
+ do |
|
183 |
+ { |
|
184 |
+ unsigned bit; |
|
185 |
+ CLzmaProb *probLit; |
|
186 |
+ matchByte <<= 1; |
|
187 |
+ bit = (matchByte & offs); |
|
188 |
+ probLit = prob + offs + bit + symbol; |
|
189 |
+ GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) |
|
190 |
+ } |
|
191 |
+ while (symbol < 0x100); |
|
192 |
+ } |
|
193 |
+ dic[dicPos++] = (Byte)symbol; |
|
194 |
+ processedPos++; |
|
195 |
+ continue; |
|
196 |
+ } |
|
197 |
+ else |
|
198 |
+ { |
|
199 |
+ UPDATE_1(prob); |
|
200 |
+ prob = probs + IsRep + state; |
|
201 |
+ IF_BIT_0(prob) |
|
202 |
+ { |
|
203 |
+ UPDATE_0(prob); |
|
204 |
+ state += kNumStates; |
|
205 |
+ prob = probs + LenCoder; |
|
206 |
+ } |
|
207 |
+ else |
|
208 |
+ { |
|
209 |
+ UPDATE_1(prob); |
|
210 |
+ if (checkDicSize == 0 && processedPos == 0) |
|
211 |
+ return SZ_ERROR_DATA; |
|
212 |
+ prob = probs + IsRepG0 + state; |
|
213 |
+ IF_BIT_0(prob) |
|
214 |
+ { |
|
215 |
+ UPDATE_0(prob); |
|
216 |
+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; |
|
217 |
+ IF_BIT_0(prob) |
|
218 |
+ { |
|
219 |
+ UPDATE_0(prob); |
|
220 |
+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; |
|
221 |
+ dicPos++; |
|
222 |
+ processedPos++; |
|
223 |
+ state = state < kNumLitStates ? 9 : 11; |
|
224 |
+ continue; |
|
225 |
+ } |
|
226 |
+ UPDATE_1(prob); |
|
227 |
+ } |
|
228 |
+ else |
|
229 |
+ { |
|
230 |
+ UInt32 distance; |
|
231 |
+ UPDATE_1(prob); |
|
232 |
+ prob = probs + IsRepG1 + state; |
|
233 |
+ IF_BIT_0(prob) |
|
234 |
+ { |
|
235 |
+ UPDATE_0(prob); |
|
236 |
+ distance = rep1; |
|
237 |
+ } |
|
238 |
+ else |
|
239 |
+ { |
|
240 |
+ UPDATE_1(prob); |
|
241 |
+ prob = probs + IsRepG2 + state; |
|
242 |
+ IF_BIT_0(prob) |
|
243 |
+ { |
|
244 |
+ UPDATE_0(prob); |
|
245 |
+ distance = rep2; |
|
246 |
+ } |
|
247 |
+ else |
|
248 |
+ { |
|
249 |
+ UPDATE_1(prob); |
|
250 |
+ distance = rep3; |
|
251 |
+ rep3 = rep2; |
|
252 |
+ } |
|
253 |
+ rep2 = rep1; |
|
254 |
+ } |
|
255 |
+ rep1 = rep0; |
|
256 |
+ rep0 = distance; |
|
257 |
+ } |
|
258 |
+ state = state < kNumLitStates ? 8 : 11; |
|
259 |
+ prob = probs + RepLenCoder; |
|
260 |
+ } |
|
261 |
+ { |
|
262 |
+ unsigned limit, offset; |
|
263 |
+ CLzmaProb *probLen = prob + LenChoice; |
|
264 |
+ IF_BIT_0(probLen) |
|
265 |
+ { |
|
266 |
+ UPDATE_0(probLen); |
|
267 |
+ probLen = prob + LenLow + (posState << kLenNumLowBits); |
|
268 |
+ offset = 0; |
|
269 |
+ limit = (1 << kLenNumLowBits); |
|
270 |
+ } |
|
271 |
+ else |
|
272 |
+ { |
|
273 |
+ UPDATE_1(probLen); |
|
274 |
+ probLen = prob + LenChoice2; |
|
275 |
+ IF_BIT_0(probLen) |
|
276 |
+ { |
|
277 |
+ UPDATE_0(probLen); |
|
278 |
+ probLen = prob + LenMid + (posState << kLenNumMidBits); |
|
279 |
+ offset = kLenNumLowSymbols; |
|
280 |
+ limit = (1 << kLenNumMidBits); |
|
281 |
+ } |
|
282 |
+ else |
|
283 |
+ { |
|
284 |
+ UPDATE_1(probLen); |
|
285 |
+ probLen = prob + LenHigh; |
|
286 |
+ offset = kLenNumLowSymbols + kLenNumMidSymbols; |
|
287 |
+ limit = (1 << kLenNumHighBits); |
|
288 |
+ } |
|
289 |
+ } |
|
290 |
+ TREE_DECODE(probLen, limit, len); |
|
291 |
+ len += offset; |
|
292 |
+ } |
|
293 |
+ |
|
294 |
+ if (state >= kNumStates) |
|
295 |
+ { |
|
296 |
+ UInt32 distance; |
|
297 |
+ prob = probs + PosSlot + |
|
298 |
+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); |
|
299 |
+ TREE_6_DECODE(prob, distance); |
|
300 |
+ if (distance >= kStartPosModelIndex) |
|
301 |
+ { |
|
302 |
+ unsigned posSlot = (unsigned)distance; |
|
303 |
+ int numDirectBits = (int)(((distance >> 1) - 1)); |
|
304 |
+ distance = (2 | (distance & 1)); |
|
305 |
+ if (posSlot < kEndPosModelIndex) |
|
306 |
+ { |
|
307 |
+ distance <<= numDirectBits; |
|
308 |
+ prob = probs + SpecPos + distance - posSlot - 1; |
|
309 |
+ { |
|
310 |
+ UInt32 mask = 1; |
|
311 |
+ unsigned i = 1; |
|
312 |
+ do |
|
313 |
+ { |
|
314 |
+ GET_BIT2(prob + i, i, ; , distance |= mask); |
|
315 |
+ mask <<= 1; |
|
316 |
+ } |
|
317 |
+ while (--numDirectBits != 0); |
|
318 |
+ } |
|
319 |
+ } |
|
320 |
+ else |
|
321 |
+ { |
|
322 |
+ numDirectBits -= kNumAlignBits; |
|
323 |
+ do |
|
324 |
+ { |
|
325 |
+ NORMALIZE |
|
326 |
+ range >>= 1; |
|
327 |
+ |
|
328 |
+ { |
|
329 |
+ UInt32 t; |
|
330 |
+ code -= range; |
|
331 |
+ t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ |
|
332 |
+ distance = (distance << 1) + (t + 1); |
|
333 |
+ code += range & t; |
|
334 |
+ } |
|
335 |
+ /* |
|
336 |
+ distance <<= 1; |
|
337 |
+ if (code >= range) |
|
338 |
+ { |
|
339 |
+ code -= range; |
|
340 |
+ distance |= 1; |
|
341 |
+ } |
|
342 |
+ */ |
|
343 |
+ } |
|
344 |
+ while (--numDirectBits != 0); |
|
345 |
+ prob = probs + Align; |
|
346 |
+ distance <<= kNumAlignBits; |
|
347 |
+ { |
|
348 |
+ unsigned i = 1; |
|
349 |
+ GET_BIT2(prob + i, i, ; , distance |= 1); |
|
350 |
+ GET_BIT2(prob + i, i, ; , distance |= 2); |
|
351 |
+ GET_BIT2(prob + i, i, ; , distance |= 4); |
|
352 |
+ GET_BIT2(prob + i, i, ; , distance |= 8); |
|
353 |
+ } |
|
354 |
+ if (distance == (UInt32)0xFFFFFFFF) |
|
355 |
+ { |
|
356 |
+ len += kMatchSpecLenStart; |
|
357 |
+ state -= kNumStates; |
|
358 |
+ break; |
|
359 |
+ } |
|
360 |
+ } |
|
361 |
+ } |
|
362 |
+ rep3 = rep2; |
|
363 |
+ rep2 = rep1; |
|
364 |
+ rep1 = rep0; |
|
365 |
+ rep0 = distance + 1; |
|
366 |
+ if (checkDicSize == 0) |
|
367 |
+ { |
|
368 |
+ if (distance >= processedPos) |
|
369 |
+ return SZ_ERROR_DATA; |
|
370 |
+ } |
|
371 |
+ else if (distance >= checkDicSize) |
|
372 |
+ return SZ_ERROR_DATA; |
|
373 |
+ state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; |
|
374 |
+ } |
|
375 |
+ |
|
376 |
+ len += kMatchMinLen; |
|
377 |
+ |
|
378 |
+ if (limit == dicPos) |
|
379 |
+ return SZ_ERROR_DATA; |
|
380 |
+ { |
|
381 |
+ SizeT rem = limit - dicPos; |
|
382 |
+ unsigned curLen = ((rem < len) ? (unsigned)rem : len); |
|
383 |
+ SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); |
|
384 |
+ |
|
385 |
+ processedPos += curLen; |
|
386 |
+ |
|
387 |
+ len -= curLen; |
|
388 |
+ if (pos + curLen <= dicBufSize) |
|
389 |
+ { |
|
390 |
+ Byte *dest = dic + dicPos; |
|
391 |
+ ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; |
|
392 |
+ const Byte *lim = dest + curLen; |
|
393 |
+ dicPos += curLen; |
|
394 |
+ do |
|
395 |
+ *(dest) = (Byte)*(dest + src); |
|
396 |
+ while (++dest != lim); |
|
397 |
+ } |
|
398 |
+ else |
|
399 |
+ { |
|
400 |
+ do |
|
401 |
+ { |
|
402 |
+ dic[dicPos++] = dic[pos]; |
|
403 |
+ if (++pos == dicBufSize) |
|
404 |
+ pos = 0; |
|
405 |
+ } |
|
406 |
+ while (--curLen != 0); |
|
407 |
+ } |
|
408 |
+ } |
|
409 |
+ } |
|
410 |
+ } |
|
411 |
+ while (dicPos < limit && buf < bufLimit); |
|
412 |
+ NORMALIZE; |
|
413 |
+ p->buf = buf; |
|
414 |
+ p->range = range; |
|
415 |
+ p->code = code; |
|
416 |
+ p->remainLen = len; |
|
417 |
+ p->dicPos = dicPos; |
|
418 |
+ p->processedPos = processedPos; |
|
419 |
+ p->reps[0] = rep0; |
|
420 |
+ p->reps[1] = rep1; |
|
421 |
+ p->reps[2] = rep2; |
|
422 |
+ p->reps[3] = rep3; |
|
423 |
+ p->state = state; |
|
424 |
+ |
|
425 |
+ return SZ_OK; |
|
426 |
+} |
|
427 |
+ |
|
428 |
+static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) |
|
429 |
+{ |
|
430 |
+ if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) |
|
431 |
+ { |
|
432 |
+ Byte *dic = p->dic; |
|
433 |
+ SizeT dicPos = p->dicPos; |
|
434 |
+ SizeT dicBufSize = p->dicBufSize; |
|
435 |
+ unsigned len = p->remainLen; |
|
436 |
+ UInt32 rep0 = p->reps[0]; |
|
437 |
+ if (limit - dicPos < len) |
|
438 |
+ len = (unsigned)(limit - dicPos); |
|
439 |
+ |
|
440 |
+ if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) |
|
441 |
+ p->checkDicSize = p->prop.dicSize; |
|
442 |
+ |
|
443 |
+ p->processedPos += len; |
|
444 |
+ p->remainLen -= len; |
|
445 |
+ while (len-- != 0) |
|
446 |
+ { |
|
447 |
+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; |
|
448 |
+ dicPos++; |
|
449 |
+ } |
|
450 |
+ p->dicPos = dicPos; |
|
451 |
+ } |
|
452 |
+} |
|
453 |
+ |
|
454 |
+static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) |
|
455 |
+{ |
|
456 |
+ do |
|
457 |
+ { |
|
458 |
+ SizeT limit2 = limit; |
|
459 |
+ if (p->checkDicSize == 0) |
|
460 |
+ { |
|
461 |
+ UInt32 rem = p->prop.dicSize - p->processedPos; |
|
462 |
+ if (limit - p->dicPos > rem) |
|
463 |
+ limit2 = p->dicPos + rem; |
|
464 |
+ } |
|
465 |
+ RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); |
|
466 |
+ if (p->processedPos >= p->prop.dicSize) |
|
467 |
+ p->checkDicSize = p->prop.dicSize; |
|
468 |
+ LzmaDec_WriteRem(p, limit); |
|
469 |
+ } |
|
470 |
+ while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); |
|
471 |
+ |
|
472 |
+ if (p->remainLen > kMatchSpecLenStart) |
|
473 |
+ { |
|
474 |
+ p->remainLen = kMatchSpecLenStart; |
|
475 |
+ } |
|
476 |
+ return 0; |
|
477 |
+} |
|
478 |
+ |
|
479 |
+typedef enum |
|
480 |
+{ |
|
481 |
+ DUMMY_ERROR, /* unexpected end of input stream */ |
|
482 |
+ DUMMY_LIT, |
|
483 |
+ DUMMY_MATCH, |
|
484 |
+ DUMMY_REP |
|
485 |
+} ELzmaDummy; |
|
486 |
+ |
|
487 |
+static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) |
|
488 |
+{ |
|
489 |
+ UInt32 range = p->range; |
|
490 |
+ UInt32 code = p->code; |
|
491 |
+ const Byte *bufLimit = buf + inSize; |
|
492 |
+ CLzmaProb *probs = p->probs; |
|
493 |
+ unsigned state = p->state; |
|
494 |
+ ELzmaDummy res; |
|
495 |
+ |
|
496 |
+ { |
|
497 |
+ CLzmaProb *prob; |
|
498 |
+ UInt32 bound; |
|
499 |
+ unsigned ttt; |
|
500 |
+ unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); |
|
501 |
+ |
|
502 |
+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; |
|
503 |
+ IF_BIT_0_CHECK(prob) |
|
504 |
+ { |
|
505 |
+ UPDATE_0_CHECK |
|
506 |
+ |
|
507 |
+ /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ |
|
508 |
+ |
|
509 |
+ prob = probs + Literal; |
|
510 |
+ if (p->checkDicSize != 0 || p->processedPos != 0) |
|
511 |
+ prob += (LZMA_LIT_SIZE * |
|
512 |
+ ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + |
|
513 |
+ (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); |
|
514 |
+ |
|
515 |
+ if (state < kNumLitStates) |
|
516 |
+ { |
|
517 |
+ unsigned symbol = 1; |
|
518 |
+ do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); |
|
519 |
+ } |
|
520 |
+ else |
|
521 |
+ { |
|
522 |
+ unsigned matchByte = p->dic[p->dicPos - p->reps[0] + |
|
523 |
+ ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; |
|
524 |
+ unsigned offs = 0x100; |
|
525 |
+ unsigned symbol = 1; |
|
526 |
+ do |
|
527 |
+ { |
|
528 |
+ unsigned bit; |
|
529 |
+ CLzmaProb *probLit; |
|
530 |
+ matchByte <<= 1; |
|
531 |
+ bit = (matchByte & offs); |
|
532 |
+ probLit = prob + offs + bit + symbol; |
|
533 |
+ GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) |
|
534 |
+ } |
|
535 |
+ while (symbol < 0x100); |
|
536 |
+ } |
|
537 |
+ res = DUMMY_LIT; |
|
538 |
+ } |
|
539 |
+ else |
|
540 |
+ { |
|
541 |
+ unsigned len; |
|
542 |
+ UPDATE_1_CHECK; |
|
543 |
+ |
|
544 |
+ prob = probs + IsRep + state; |
|
545 |
+ IF_BIT_0_CHECK(prob) |
|
546 |
+ { |
|
547 |
+ UPDATE_0_CHECK; |
|
548 |
+ state = 0; |
|
549 |
+ prob = probs + LenCoder; |
|
550 |
+ res = DUMMY_MATCH; |
|
551 |
+ } |
|
552 |
+ else |
|
553 |
+ { |
|
554 |
+ UPDATE_1_CHECK; |
|
555 |
+ res = DUMMY_REP; |
|
556 |
+ prob = probs + IsRepG0 + state; |
|
557 |
+ IF_BIT_0_CHECK(prob) |
|
558 |
+ { |
|
559 |
+ UPDATE_0_CHECK; |
|
560 |
+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; |
|
561 |
+ IF_BIT_0_CHECK(prob) |
|
562 |
+ { |
|
563 |
+ UPDATE_0_CHECK; |
|
564 |
+ NORMALIZE_CHECK; |
|
565 |
+ return DUMMY_REP; |
|
566 |
+ } |
|
567 |
+ else |
|
568 |
+ { |
|
569 |
+ UPDATE_1_CHECK; |
|
570 |
+ } |
|
571 |
+ } |
|
572 |
+ else |
|
573 |
+ { |
|
574 |
+ UPDATE_1_CHECK; |
|
575 |
+ prob = probs + IsRepG1 + state; |
|
576 |
+ IF_BIT_0_CHECK(prob) |
|
577 |
+ { |
|
578 |
+ UPDATE_0_CHECK; |
|
579 |
+ } |
|
580 |
+ else |
|
581 |
+ { |
|
582 |
+ UPDATE_1_CHECK; |
|
583 |
+ prob = probs + IsRepG2 + state; |
|
584 |
+ IF_BIT_0_CHECK(prob) |
|
585 |
+ { |
|
586 |
+ UPDATE_0_CHECK; |
|
587 |
+ } |
|
588 |
+ else |
|
589 |
+ { |
|
590 |
+ UPDATE_1_CHECK; |
|
591 |
+ } |
|
592 |
+ } |
|
593 |
+ } |
|
594 |
+ state = kNumStates; |
|
595 |
+ prob = probs + RepLenCoder; |
|
596 |
+ } |
|
597 |
+ { |
|
598 |
+ unsigned limit, offset; |
|
599 |
+ CLzmaProb *probLen = prob + LenChoice; |
|
600 |
+ IF_BIT_0_CHECK(probLen) |
|
601 |
+ { |
|
602 |
+ UPDATE_0_CHECK; |
|
603 |
+ probLen = prob + LenLow + (posState << kLenNumLowBits); |
|
604 |
+ offset = 0; |
|
605 |
+ limit = 1 << kLenNumLowBits; |
|
606 |
+ } |
|
607 |
+ else |
|
608 |
+ { |
|
609 |
+ UPDATE_1_CHECK; |
|
610 |
+ probLen = prob + LenChoice2; |
|
611 |
+ IF_BIT_0_CHECK(probLen) |
|
612 |
+ { |
|
613 |
+ UPDATE_0_CHECK; |
|
614 |
+ probLen = prob + LenMid + (posState << kLenNumMidBits); |
|
615 |
+ offset = kLenNumLowSymbols; |
|
616 |
+ limit = 1 << kLenNumMidBits; |
|
617 |
+ } |
|
618 |
+ else |
|
619 |
+ { |
|
620 |
+ UPDATE_1_CHECK; |
|
621 |
+ probLen = prob + LenHigh; |
|
622 |
+ offset = kLenNumLowSymbols + kLenNumMidSymbols; |
|
623 |
+ limit = 1 << kLenNumHighBits; |
|
624 |
+ } |
|
625 |
+ } |
|
626 |
+ TREE_DECODE_CHECK(probLen, limit, len); |
|
627 |
+ len += offset; |
|
628 |
+ } |
|
629 |
+ |
|
630 |
+ if (state < 4) |
|
631 |
+ { |
|
632 |
+ unsigned posSlot; |
|
633 |
+ prob = probs + PosSlot + |
|
634 |
+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << |
|
635 |
+ kNumPosSlotBits); |
|
636 |
+ TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); |
|
637 |
+ if (posSlot >= kStartPosModelIndex) |
|
638 |
+ { |
|
639 |
+ int numDirectBits = ((posSlot >> 1) - 1); |
|
640 |
+ |
|
641 |
+ /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ |
|
642 |
+ |
|
643 |
+ if (posSlot < kEndPosModelIndex) |
|
644 |
+ { |
|
645 |
+ prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; |
|
646 |
+ } |
|
647 |
+ else |
|
648 |
+ { |
|
649 |
+ numDirectBits -= kNumAlignBits; |
|
650 |
+ do |
|
651 |
+ { |
|
652 |
+ NORMALIZE_CHECK |
|
653 |
+ range >>= 1; |
|
654 |
+ code -= range & (((code - range) >> 31) - 1); |
|
655 |
+ /* if (code >= range) code -= range; */ |
|
656 |
+ } |
|
657 |
+ while (--numDirectBits != 0); |
|
658 |
+ prob = probs + Align; |
|
659 |
+ numDirectBits = kNumAlignBits; |
|
660 |
+ } |
|
661 |
+ { |
|
662 |
+ unsigned i = 1; |
|
663 |
+ do |
|
664 |
+ { |
|
665 |
+ GET_BIT_CHECK(prob + i, i); |
|
666 |
+ } |
|
667 |
+ while (--numDirectBits != 0); |
|
668 |
+ } |
|
669 |
+ } |
|
670 |
+ } |
|
671 |
+ } |
|
672 |
+ } |
|
673 |
+ NORMALIZE_CHECK; |
|
674 |
+ return res; |
|
675 |
+} |
|
676 |
+ |
|
677 |
+ |
|
678 |
+static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) |
|
679 |
+{ |
|
680 |
+ p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); |
|
681 |
+ p->range = 0xFFFFFFFF; |
|
682 |
+ p->needFlush = 0; |
|
683 |
+} |
|
684 |
+ |
|
685 |
+void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) |
|
686 |
+{ |
|
687 |
+ p->needFlush = 1; |
|
688 |
+ p->remainLen = 0; |
|
689 |
+ p->tempBufSize = 0; |
|
690 |
+ |
|
691 |
+ if (initDic) |
|
692 |
+ { |
|
693 |
+ p->processedPos = 0; |
|
694 |
+ p->checkDicSize = 0; |
|
695 |
+ p->needInitState = 1; |
|
696 |
+ } |
|
697 |
+ if (initState) |
|
698 |
+ p->needInitState = 1; |
|
699 |
+} |
|
700 |
+ |
|
701 |
+void LzmaDec_Init(CLzmaDec *p) |
|
702 |
+{ |
|
703 |
+ p->dicPos = 0; |
|
704 |
+ LzmaDec_InitDicAndState(p, True, True); |
|
705 |
+} |
|
706 |
+ |
|
707 |
+static void LzmaDec_InitStateReal(CLzmaDec *p) |
|
708 |
+{ |
|
709 |
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); |
|
710 |
+ UInt32 i; |
|
711 |
+ CLzmaProb *probs = p->probs; |
|
712 |
+ for (i = 0; i < numProbs; i++) |
|
713 |
+ probs[i] = kBitModelTotal >> 1; |
|
714 |
+ p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; |
|
715 |
+ p->state = 0; |
|
716 |
+ p->needInitState = 0; |
|
717 |
+} |
|
718 |
+ |
|
719 |
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, |
|
720 |
+ ELzmaFinishMode finishMode, ELzmaStatus *status) |
|
721 |
+{ |
|
722 |
+ SizeT inSize = *srcLen; |
|
723 |
+ (*srcLen) = 0; |
|
724 |
+ LzmaDec_WriteRem(p, dicLimit); |
|
725 |
+ |
|
726 |
+ *status = LZMA_STATUS_NOT_SPECIFIED; |
|
727 |
+ |
|
728 |
+ while (p->remainLen != kMatchSpecLenStart) |
|
729 |
+ { |
|
730 |
+ int checkEndMarkNow; |
|
731 |
+ |
|
732 |
+ if (p->needFlush != 0) |
|
733 |
+ { |
|
734 |
+ for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) |
|
735 |
+ p->tempBuf[p->tempBufSize++] = *src++; |
|
736 |
+ if (p->tempBufSize < RC_INIT_SIZE) |
|
737 |
+ { |
|
738 |
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT; |
|
739 |
+ return SZ_OK; |
|
740 |
+ } |
|
741 |
+ if (p->tempBuf[0] != 0) |
|
742 |
+ return SZ_ERROR_DATA; |
|
743 |
+ |
|
744 |
+ LzmaDec_InitRc(p, p->tempBuf); |
|
745 |
+ p->tempBufSize = 0; |
|
746 |
+ } |
|
747 |
+ |
|
748 |
+ checkEndMarkNow = 0; |
|
749 |
+ if (p->dicPos >= dicLimit) |
|
750 |
+ { |
|
751 |
+ if (p->remainLen == 0 && p->code == 0) |
|
752 |
+ { |
|
753 |
+ *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; |
|
754 |
+ return SZ_OK; |
|
755 |
+ } |
|
756 |
+ if (finishMode == LZMA_FINISH_ANY) |
|
757 |
+ { |
|
758 |
+ *status = LZMA_STATUS_NOT_FINISHED; |
|
759 |
+ return SZ_OK; |
|
760 |
+ } |
|
761 |
+ if (p->remainLen != 0) |
|
762 |
+ { |
|
763 |
+ *status = LZMA_STATUS_NOT_FINISHED; |
|
764 |
+ return SZ_ERROR_DATA; |
|
765 |
+ } |
|
766 |
+ checkEndMarkNow = 1; |
|
767 |
+ } |
|
768 |
+ |
|
769 |
+ if (p->needInitState) |
|
770 |
+ LzmaDec_InitStateReal(p); |
|
771 |
+ |
|
772 |
+ if (p->tempBufSize == 0) |
|
773 |
+ { |
|
774 |
+ SizeT processed; |
|
775 |
+ const Byte *bufLimit; |
|
776 |
+ if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) |
|
777 |
+ { |
|
778 |
+ int dummyRes = LzmaDec_TryDummy(p, src, inSize); |
|
779 |
+ if (dummyRes == DUMMY_ERROR) |
|
780 |
+ { |
|
781 |
+ memcpy(p->tempBuf, src, inSize); |
|
782 |
+ p->tempBufSize = (unsigned)inSize; |
|
783 |
+ (*srcLen) += inSize; |
|
784 |
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT; |
|
785 |
+ return SZ_OK; |
|
786 |
+ } |
|
787 |
+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH) |
|
788 |
+ { |
|
789 |
+ *status = LZMA_STATUS_NOT_FINISHED; |
|
790 |
+ return SZ_ERROR_DATA; |
|
791 |
+ } |
|
792 |
+ bufLimit = src; |
|
793 |
+ } |
|
794 |
+ else |
|
795 |
+ bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; |
|
796 |
+ p->buf = src; |
|
797 |
+ if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) |
|
798 |
+ return SZ_ERROR_DATA; |
|
799 |
+ processed = (SizeT)(p->buf - src); |
|
800 |
+ (*srcLen) += processed; |
|
801 |
+ src += processed; |
|
802 |
+ inSize -= processed; |
|
803 |
+ } |
|
804 |
+ else |
|
805 |
+ { |
|
806 |
+ unsigned rem = p->tempBufSize, lookAhead = 0; |
|
807 |
+ while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) |
|
808 |
+ p->tempBuf[rem++] = src[lookAhead++]; |
|
809 |
+ p->tempBufSize = rem; |
|
810 |
+ if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) |
|
811 |
+ { |
|
812 |
+ int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); |
|
813 |
+ if (dummyRes == DUMMY_ERROR) |
|
814 |
+ { |
|
815 |
+ (*srcLen) += lookAhead; |
|
816 |
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT; |
|
817 |
+ return SZ_OK; |
|
818 |
+ } |
|
819 |
+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH) |
|
820 |
+ { |
|
821 |
+ *status = LZMA_STATUS_NOT_FINISHED; |
|
822 |
+ return SZ_ERROR_DATA; |
|
823 |
+ } |
|
824 |
+ } |
|
825 |
+ p->buf = p->tempBuf; |
|
826 |
+ if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) |
|
827 |
+ return SZ_ERROR_DATA; |
|
828 |
+ lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); |
|
829 |
+ (*srcLen) += lookAhead; |
|
830 |
+ src += lookAhead; |
|
831 |
+ inSize -= lookAhead; |
|
832 |
+ p->tempBufSize = 0; |
|
833 |
+ } |
|
834 |
+ } |
|
835 |
+ if (p->code == 0) |
|
836 |
+ *status = LZMA_STATUS_FINISHED_WITH_MARK; |
|
837 |
+ return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; |
|
838 |
+} |
|
839 |
+ |
|
840 |
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) |
|
841 |
+{ |
|
842 |
+ SizeT outSize = *destLen; |
|
843 |
+ SizeT inSize = *srcLen; |
|
844 |
+ *srcLen = *destLen = 0; |
|
845 |
+ for (;;) |
|
846 |
+ { |
|
847 |
+ SizeT inSizeCur = inSize, outSizeCur, dicPos; |
|
848 |
+ ELzmaFinishMode curFinishMode; |
|
849 |
+ SRes res; |
|
850 |
+ if (p->dicPos == p->dicBufSize) |
|
851 |
+ p->dicPos = 0; |
|
852 |
+ dicPos = p->dicPos; |
|
853 |
+ if (outSize > p->dicBufSize - dicPos) |
|
854 |
+ { |
|
855 |
+ outSizeCur = p->dicBufSize; |
|
856 |
+ curFinishMode = LZMA_FINISH_ANY; |
|
857 |
+ } |
|
858 |
+ else |
|
859 |
+ { |
|
860 |
+ outSizeCur = dicPos + outSize; |
|
861 |
+ curFinishMode = finishMode; |
|
862 |
+ } |
|
863 |
+ |
|
864 |
+ res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); |
|
865 |
+ src += inSizeCur; |
|
866 |
+ inSize -= inSizeCur; |
|
867 |
+ *srcLen += inSizeCur; |
|
868 |
+ outSizeCur = p->dicPos - dicPos; |
|
869 |
+ memcpy(dest, p->dic + dicPos, outSizeCur); |
|
870 |
+ dest += outSizeCur; |
|
871 |
+ outSize -= outSizeCur; |
|
872 |
+ *destLen += outSizeCur; |
|
873 |
+ if (res != 0) |
|
874 |
+ return res; |
|
875 |
+ if (outSizeCur == 0 || outSize == 0) |
|
876 |
+ return SZ_OK; |
|
877 |
+ } |
|
878 |
+} |
|
879 |
+ |
|
880 |
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) |
|
881 |
+{ |
|
882 |
+ alloc->Free(alloc, p->probs); |
|
883 |
+ p->probs = 0; |
|
884 |
+} |
|
885 |
+ |
|
886 |
+static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) |
|
887 |
+{ |
|
888 |
+ alloc->Free(alloc, p->dic); |
|
889 |
+ p->dic = 0; |
|
890 |
+} |
|
891 |
+ |
|
892 |
+void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) |
|
893 |
+{ |
|
894 |
+ LzmaDec_FreeProbs(p, alloc); |
|
895 |
+ LzmaDec_FreeDict(p, alloc); |
|
896 |
+} |
|
897 |
+ |
|
898 |
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) |
|
899 |
+{ |
|
900 |
+ UInt32 dicSize; |
|
901 |
+ Byte d; |
|
902 |
+ |
|
903 |
+ if (size < LZMA_PROPS_SIZE) |
|
904 |
+ return SZ_ERROR_UNSUPPORTED; |
|
905 |
+ else |
|
906 |
+ dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); |
|
907 |
+ |
|
908 |
+ if (dicSize < LZMA_DIC_MIN) |
|
909 |
+ dicSize = LZMA_DIC_MIN; |
|
910 |
+ p->dicSize = dicSize; |
|
911 |
+ |
|
912 |
+ d = data[0]; |
|
913 |
+ if (d >= (9 * 5 * 5)) |
|
914 |
+ return SZ_ERROR_UNSUPPORTED; |
|
915 |
+ |
|
916 |
+ p->lc = d % 9; |
|
917 |
+ d /= 9; |
|
918 |
+ p->pb = d / 5; |
|
919 |
+ p->lp = d % 5; |
|
920 |
+ |
|
921 |
+ return SZ_OK; |
|
922 |
+} |
|
923 |
+ |
|
924 |
+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) |
|
925 |
+{ |
|
926 |
+ UInt32 numProbs = LzmaProps_GetNumProbs(propNew); |
|
927 |
+ if (p->probs == 0 || numProbs != p->numProbs) |
|
928 |
+ { |
|
929 |
+ LzmaDec_FreeProbs(p, alloc); |
|
930 |
+ p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); |
|
931 |
+ p->numProbs = numProbs; |
|
932 |
+ if (p->probs == 0) |
|
933 |
+ return SZ_ERROR_MEM; |
|
934 |
+ } |
|
935 |
+ return SZ_OK; |
|
936 |
+} |
|
937 |
+ |
|
938 |
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) |
|
939 |
+{ |
|
940 |
+ CLzmaProps propNew; |
|
941 |
+ RINOK(LzmaProps_Decode(&propNew, props, propsSize)); |
|
942 |
+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); |
|
943 |
+ p->prop = propNew; |
|
944 |
+ return SZ_OK; |
|
945 |
+} |
|
946 |
+ |
|
947 |
+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) |
|
948 |
+{ |
|
949 |
+ CLzmaProps propNew; |
|
950 |
+ SizeT dicBufSize; |
|
951 |
+ RINOK(LzmaProps_Decode(&propNew, props, propsSize)); |
|
952 |
+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); |
|
953 |
+ dicBufSize = propNew.dicSize; |
|
954 |
+ if (p->dic == 0 || dicBufSize != p->dicBufSize) |
|
955 |
+ { |
|
956 |
+ LzmaDec_FreeDict(p, alloc); |
|
957 |
+ p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); |
|
958 |
+ if (p->dic == 0) |
|
959 |
+ { |
|
960 |
+ LzmaDec_FreeProbs(p, alloc); |
|
961 |
+ return SZ_ERROR_MEM; |
|
962 |
+ } |
|
963 |
+ } |
|
964 |
+ p->dicBufSize = dicBufSize; |
|
965 |
+ p->prop = propNew; |
|
966 |
+ return SZ_OK; |
|
967 |
+} |
|
968 |
+ |
|
969 |
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, |
|
970 |
+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, |
|
971 |
+ ELzmaStatus *status, ISzAlloc *alloc) |
|
972 |
+{ |
|
973 |
+ CLzmaDec p; |
|
974 |
+ SRes res; |
|
975 |
+ SizeT inSize = *srcLen; |
|
976 |
+ SizeT outSize = *destLen; |
|
977 |
+ *srcLen = *destLen = 0; |
|
978 |
+ if (inSize < RC_INIT_SIZE) |
|
979 |
+ return SZ_ERROR_INPUT_EOF; |
|
980 |
+ |
|
981 |
+ LzmaDec_Construct(&p); |
|
982 |
+ res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); |
|
983 |
+ if (res != 0) |
|
984 |
+ return res; |
|
985 |
+ p.dic = dest; |
|
986 |
+ p.dicBufSize = outSize; |
|
987 |
+ |
|
988 |
+ LzmaDec_Init(&p); |
|
989 |
+ |
|
990 |
+ *srcLen = inSize; |
|
991 |
+ res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); |
|
992 |
+ |
|
993 |
+ if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) |
|
994 |
+ res = SZ_ERROR_INPUT_EOF; |
|
995 |
+ |
|
996 |
+ (*destLen) = p.dicPos; |
|
997 |
+ LzmaDec_FreeProbs(&p, alloc); |
|
998 |
+ return res; |
|
999 |
+} |
... | ... |
@@ -1,223 +1,231 @@ |
1 |
-/* LzmaDec.h -- LZMA Decoder |
|
2 |
-2008-10-04 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#ifndef __LZMADEC_H |
|
5 |
-#define __LZMADEC_H |
|
6 |
- |
|
7 |
-#include "Types.h" |
|
8 |
- |
|
9 |
-/* #define _LZMA_PROB32 */ |
|
10 |
-/* _LZMA_PROB32 can increase the speed on some CPUs, |
|
11 |
- but memory usage for CLzmaDec::probs will be doubled in that case */ |
|
12 |
- |
|
13 |
-#ifdef _LZMA_PROB32 |
|
14 |
-#define CLzmaProb UInt32 |
|
15 |
-#else |
|
16 |
-#define CLzmaProb UInt16 |
|
17 |
-#endif |
|
18 |
- |
|
19 |
- |
|
20 |
-/* ---------- LZMA Properties ---------- */ |
|
21 |
- |
|
22 |
-#define LZMA_PROPS_SIZE 5 |
|
23 |
- |
|
24 |
-typedef struct _CLzmaProps |
|
25 |
-{ |
|
26 |
- unsigned lc, lp, pb; |
|
27 |
- UInt32 dicSize; |
|
28 |
-} CLzmaProps; |
|
29 |
- |
|
30 |
-/* LzmaProps_Decode - decodes properties |
|
31 |
-Returns: |
|
32 |
- SZ_OK |
|
33 |
- SZ_ERROR_UNSUPPORTED - Unsupported properties |
|
34 |
-*/ |
|
35 |
- |
|
36 |
-SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); |
|
37 |
- |
|
38 |
- |
|
39 |
-/* ---------- LZMA Decoder state ---------- */ |
|
40 |
- |
|
41 |
-/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. |
|
42 |
- Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ |
|
43 |
- |
|
44 |
-#define LZMA_REQUIRED_INPUT_MAX 20 |
|
45 |
- |
|
46 |
-typedef struct |
|
47 |
-{ |
|
48 |
- CLzmaProps prop; |
|
49 |
- CLzmaProb *probs; |
|
50 |
- Byte *dic; |
|
51 |
- const Byte *buf; |
|
52 |
- UInt32 range, code; |
|
53 |
- SizeT dicPos; |
|
54 |
- SizeT dicBufSize; |
|
55 |
- UInt32 processedPos; |
|
56 |
- UInt32 checkDicSize; |
|
57 |
- unsigned state; |
|
58 |
- UInt32 reps[4]; |
|
59 |
- unsigned remainLen; |
|
60 |
- int needFlush; |
|
61 |
- int needInitState; |
|
62 |
- UInt32 numProbs; |
|
63 |
- unsigned tempBufSize; |
|
64 |
- Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; |
|
65 |
-} CLzmaDec; |
|
66 |
- |
|
67 |
-#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } |
|
68 |
- |
|
69 |
-void LzmaDec_Init(CLzmaDec *p); |
|
70 |
- |
|
71 |
-/* There are two types of LZMA streams: |
|
72 |
- 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. |
|
73 |
- 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ |
|
74 |
- |
|
75 |
-typedef enum |
|
76 |
-{ |
|
77 |
- LZMA_FINISH_ANY, /* finish at any point */ |
|
78 |
- LZMA_FINISH_END /* block must be finished at the end */ |
|
79 |
-} ELzmaFinishMode; |
|
80 |
- |
|
81 |
-/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! |
|
82 |
- |
|
83 |
- You must use LZMA_FINISH_END, when you know that current output buffer |
|
84 |
- covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. |
|
85 |
- |
|
86 |
- If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, |
|
87 |
- and output value of destLen will be less than output buffer size limit. |
|
88 |
- You can check status result also. |
|
89 |
- |
|
90 |
- You can use multiple checks to test data integrity after full decompression: |
|
91 |
- 1) Check Result and "status" variable. |
|
92 |
- 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. |
|
93 |
- 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. |
|
94 |
- You must use correct finish mode in that case. */ |
|
95 |
- |
|
96 |
-typedef enum |
|
97 |
-{ |
|
98 |
- LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ |
|
99 |
- LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ |
|
100 |
- LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ |
|
101 |
- LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ |
|
102 |
- LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ |
|
103 |
-} ELzmaStatus; |
|
104 |
- |
|
105 |
-/* ELzmaStatus is used only as output value for function call */ |
|
106 |
- |
|
107 |
- |
|
108 |
-/* ---------- Interfaces ---------- */ |
|
109 |
- |
|
110 |
-/* There are 3 levels of interfaces: |
|
111 |
- 1) Dictionary Interface |
|
112 |
- 2) Buffer Interface |
|
113 |
- 3) One Call Interface |
|
114 |
- You can select any of these interfaces, but don't mix functions from different |
|
115 |
- groups for same object. */ |
|
116 |
- |
|
117 |
- |
|
118 |
-/* There are two variants to allocate state for Dictionary Interface: |
|
119 |
- 1) LzmaDec_Allocate / LzmaDec_Free |
|
120 |
- 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs |
|
121 |
- You can use variant 2, if you set dictionary buffer manually. |
|
122 |
- For Buffer Interface you must always use variant 1. |
|
123 |
- |
|
124 |
-LzmaDec_Allocate* can return: |
|
125 |
- SZ_OK |
|
126 |
- SZ_ERROR_MEM - Memory allocation error |
|
127 |
- SZ_ERROR_UNSUPPORTED - Unsupported properties |
|
128 |
-*/ |
|
129 |
- |
|
130 |
-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); |
|
131 |
-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); |
|
132 |
- |
|
133 |
-SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); |
|
134 |
-void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); |
|
135 |
- |
|
136 |
-/* ---------- Dictionary Interface ---------- */ |
|
137 |
- |
|
138 |
-/* You can use it, if you want to eliminate the overhead for data copying from |
|
139 |
- dictionary to some other external buffer. |
|
140 |
- You must work with CLzmaDec variables directly in this interface. |
|
141 |
- |
|
142 |
- STEPS: |
|
143 |
- LzmaDec_Constr() |
|
144 |
- LzmaDec_Allocate() |
|
145 |
- for (each new stream) |
|
146 |
- { |
|
147 |
- LzmaDec_Init() |
|
148 |
- while (it needs more decompression) |
|
149 |
- { |
|
150 |
- LzmaDec_DecodeToDic() |
|
151 |
- use data from CLzmaDec::dic and update CLzmaDec::dicPos |
|
152 |
- } |
|
153 |
- } |
|
154 |
- LzmaDec_Free() |
|
155 |
-*/ |
|
156 |
- |
|
157 |
-/* LzmaDec_DecodeToDic |
|
158 |
- |
|
159 |
- The decoding to internal dictionary buffer (CLzmaDec::dic). |
|
160 |
- You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! |
|
161 |
- |
|
162 |
-finishMode: |
|
163 |
- It has meaning only if the decoding reaches output limit (dicLimit). |
|
164 |
- LZMA_FINISH_ANY - Decode just dicLimit bytes. |
|
165 |
- LZMA_FINISH_END - Stream must be finished after dicLimit. |
|
166 |
- |
|
167 |
-Returns: |
|
168 |
- SZ_OK |
|
169 |
- status: |
|
170 |
- LZMA_STATUS_FINISHED_WITH_MARK |
|
171 |
- LZMA_STATUS_NOT_FINISHED |
|
172 |
- LZMA_STATUS_NEEDS_MORE_INPUT |
|
173 |
- LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK |
|
174 |
- SZ_ERROR_DATA - Data error |
|
175 |
-*/ |
|
176 |
- |
|
177 |
-SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, |
|
178 |
- const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); |
|
179 |
- |
|
180 |
- |
|
181 |
-/* ---------- Buffer Interface ---------- */ |
|
182 |
- |
|
183 |
-/* It's zlib-like interface. |
|
184 |
- See LzmaDec_DecodeToDic description for information about STEPS and return results, |
|
185 |
- but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need |
|
186 |
- to work with CLzmaDec variables manually. |
|
187 |
- |
|
188 |
-finishMode: |
|
189 |
- It has meaning only if the decoding reaches output limit (*destLen). |
|
190 |
- LZMA_FINISH_ANY - Decode just destLen bytes. |
|
191 |
- LZMA_FINISH_END - Stream must be finished after (*destLen). |
|
192 |
-*/ |
|
193 |
- |
|
194 |
-SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, |
|
195 |
- const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); |
|
196 |
- |
|
197 |
- |
|
198 |
-/* ---------- One Call Interface ---------- */ |
|
199 |
- |
|
200 |
-/* LzmaDecode |
|
201 |
- |
|
202 |
-finishMode: |
|
203 |
- It has meaning only if the decoding reaches output limit (*destLen). |
|
204 |
- LZMA_FINISH_ANY - Decode just destLen bytes. |
|
205 |
- LZMA_FINISH_END - Stream must be finished after (*destLen). |
|
206 |
- |
|
207 |
-Returns: |
|
208 |
- SZ_OK |
|
209 |
- status: |
|
210 |
- LZMA_STATUS_FINISHED_WITH_MARK |
|
211 |
- LZMA_STATUS_NOT_FINISHED |
|
212 |
- LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK |
|
213 |
- SZ_ERROR_DATA - Data error |
|
214 |
- SZ_ERROR_MEM - Memory allocation error |
|
215 |
- SZ_ERROR_UNSUPPORTED - Unsupported properties |
|
216 |
- SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). |
|
217 |
-*/ |
|
218 |
- |
|
219 |
-SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, |
|
220 |
- const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, |
|
221 |
- ELzmaStatus *status, ISzAlloc *alloc); |
|
222 |
- |
|
223 |
-#endif |
|
1 |
+/* LzmaDec.h -- LZMA Decoder |
|
2 |
+2009-02-07 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#ifndef __LZMA_DEC_H |
|
5 |
+#define __LZMA_DEC_H |
|
6 |
+ |
|
7 |
+#include "Types.h" |
|
8 |
+ |
|
9 |
+#ifdef __cplusplus |
|
10 |
+extern "C" { |
|
11 |
+#endif |
|
12 |
+ |
|
13 |
+/* #define _LZMA_PROB32 */ |
|
14 |
+/* _LZMA_PROB32 can increase the speed on some CPUs, |
|
15 |
+ but memory usage for CLzmaDec::probs will be doubled in that case */ |
|
16 |
+ |
|
17 |
+#ifdef _LZMA_PROB32 |
|
18 |
+#define CLzmaProb UInt32 |
|
19 |
+#else |
|
20 |
+#define CLzmaProb UInt16 |
|
21 |
+#endif |
|
22 |
+ |
|
23 |
+ |
|
24 |
+/* ---------- LZMA Properties ---------- */ |
|
25 |
+ |
|
26 |
+#define LZMA_PROPS_SIZE 5 |
|
27 |
+ |
|
28 |
+typedef struct _CLzmaProps |
|
29 |
+{ |
|
30 |
+ unsigned lc, lp, pb; |
|
31 |
+ UInt32 dicSize; |
|
32 |
+} CLzmaProps; |
|
33 |
+ |
|
34 |
+/* LzmaProps_Decode - decodes properties |
|
35 |
+Returns: |
|
36 |
+ SZ_OK |
|
37 |
+ SZ_ERROR_UNSUPPORTED - Unsupported properties |
|
38 |
+*/ |
|
39 |
+ |
|
40 |
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); |
|
41 |
+ |
|
42 |
+ |
|
43 |
+/* ---------- LZMA Decoder state ---------- */ |
|
44 |
+ |
|
45 |
+/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. |
|
46 |
+ Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ |
|
47 |
+ |
|
48 |
+#define LZMA_REQUIRED_INPUT_MAX 20 |
|
49 |
+ |
|
50 |
+typedef struct |
|
51 |
+{ |
|
52 |
+ CLzmaProps prop; |
|
53 |
+ CLzmaProb *probs; |
|
54 |
+ Byte *dic; |
|
55 |
+ const Byte *buf; |
|
56 |
+ UInt32 range, code; |
|
57 |
+ SizeT dicPos; |
|
58 |
+ SizeT dicBufSize; |
|
59 |
+ UInt32 processedPos; |
|
60 |
+ UInt32 checkDicSize; |
|
61 |
+ unsigned state; |
|
62 |
+ UInt32 reps[4]; |
|
63 |
+ unsigned remainLen; |
|
64 |
+ int needFlush; |
|
65 |
+ int needInitState; |
|
66 |
+ UInt32 numProbs; |
|
67 |
+ unsigned tempBufSize; |
|
68 |
+ Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; |
|
69 |
+} CLzmaDec; |
|
70 |
+ |
|
71 |
+#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } |
|
72 |
+ |
|
73 |
+void LzmaDec_Init(CLzmaDec *p); |
|
74 |
+ |
|
75 |
+/* There are two types of LZMA streams: |
|
76 |
+ 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. |
|
77 |
+ 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ |
|
78 |
+ |
|
79 |
+typedef enum |
|
80 |
+{ |
|
81 |
+ LZMA_FINISH_ANY, /* finish at any point */ |
|
82 |
+ LZMA_FINISH_END /* block must be finished at the end */ |
|
83 |
+} ELzmaFinishMode; |
|
84 |
+ |
|
85 |
+/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! |
|
86 |
+ |
|
87 |
+ You must use LZMA_FINISH_END, when you know that current output buffer |
|
88 |
+ covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. |
|
89 |
+ |
|
90 |
+ If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, |
|
91 |
+ and output value of destLen will be less than output buffer size limit. |
|
92 |
+ You can check status result also. |
|
93 |
+ |
|
94 |
+ You can use multiple checks to test data integrity after full decompression: |
|
95 |
+ 1) Check Result and "status" variable. |
|
96 |
+ 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. |
|
97 |
+ 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. |
|
98 |
+ You must use correct finish mode in that case. */ |
|
99 |
+ |
|
100 |
+typedef enum |
|
101 |
+{ |
|
102 |
+ LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ |
|
103 |
+ LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ |
|
104 |
+ LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ |
|
105 |
+ LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ |
|
106 |
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ |
|
107 |
+} ELzmaStatus; |
|
108 |
+ |
|
109 |
+/* ELzmaStatus is used only as output value for function call */ |
|
110 |
+ |
|
111 |
+ |
|
112 |
+/* ---------- Interfaces ---------- */ |
|
113 |
+ |
|
114 |
+/* There are 3 levels of interfaces: |
|
115 |
+ 1) Dictionary Interface |
|
116 |
+ 2) Buffer Interface |
|
117 |
+ 3) One Call Interface |
|
118 |
+ You can select any of these interfaces, but don't mix functions from different |
|
119 |
+ groups for same object. */ |
|
120 |
+ |
|
121 |
+ |
|
122 |
+/* There are two variants to allocate state for Dictionary Interface: |
|
123 |
+ 1) LzmaDec_Allocate / LzmaDec_Free |
|
124 |
+ 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs |
|
125 |
+ You can use variant 2, if you set dictionary buffer manually. |
|
126 |
+ For Buffer Interface you must always use variant 1. |
|
127 |
+ |
|
128 |
+LzmaDec_Allocate* can return: |
|
129 |
+ SZ_OK |
|
130 |
+ SZ_ERROR_MEM - Memory allocation error |
|
131 |
+ SZ_ERROR_UNSUPPORTED - Unsupported properties |
|
132 |
+*/ |
|
133 |
+ |
|
134 |
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); |
|
135 |
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); |
|
136 |
+ |
|
137 |
+SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); |
|
138 |
+void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); |
|
139 |
+ |
|
140 |
+/* ---------- Dictionary Interface ---------- */ |
|
141 |
+ |
|
142 |
+/* You can use it, if you want to eliminate the overhead for data copying from |
|
143 |
+ dictionary to some other external buffer. |
|
144 |
+ You must work with CLzmaDec variables directly in this interface. |
|
145 |
+ |
|
146 |
+ STEPS: |
|
147 |
+ LzmaDec_Constr() |
|
148 |
+ LzmaDec_Allocate() |
|
149 |
+ for (each new stream) |
|
150 |
+ { |
|
151 |
+ LzmaDec_Init() |
|
152 |
+ while (it needs more decompression) |
|
153 |
+ { |
|
154 |
+ LzmaDec_DecodeToDic() |
|
155 |
+ use data from CLzmaDec::dic and update CLzmaDec::dicPos |
|
156 |
+ } |
|
157 |
+ } |
|
158 |
+ LzmaDec_Free() |
|
159 |
+*/ |
|
160 |
+ |
|
161 |
+/* LzmaDec_DecodeToDic |
|
162 |
+ |
|
163 |
+ The decoding to internal dictionary buffer (CLzmaDec::dic). |
|
164 |
+ You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! |
|
165 |
+ |
|
166 |
+finishMode: |
|
167 |
+ It has meaning only if the decoding reaches output limit (dicLimit). |
|
168 |
+ LZMA_FINISH_ANY - Decode just dicLimit bytes. |
|
169 |
+ LZMA_FINISH_END - Stream must be finished after dicLimit. |
|
170 |
+ |
|
171 |
+Returns: |
|
172 |
+ SZ_OK |
|
173 |
+ status: |
|
174 |
+ LZMA_STATUS_FINISHED_WITH_MARK |
|
175 |
+ LZMA_STATUS_NOT_FINISHED |
|
176 |
+ LZMA_STATUS_NEEDS_MORE_INPUT |
|
177 |
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK |
|
178 |
+ SZ_ERROR_DATA - Data error |
|
179 |
+*/ |
|
180 |
+ |
|
181 |
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, |
|
182 |
+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); |
|
183 |
+ |
|
184 |
+ |
|
185 |
+/* ---------- Buffer Interface ---------- */ |
|
186 |
+ |
|
187 |
+/* It's zlib-like interface. |
|
188 |
+ See LzmaDec_DecodeToDic description for information about STEPS and return results, |
|
189 |
+ but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need |
|
190 |
+ to work with CLzmaDec variables manually. |
|
191 |
+ |
|
192 |
+finishMode: |
|
193 |
+ It has meaning only if the decoding reaches output limit (*destLen). |
|
194 |
+ LZMA_FINISH_ANY - Decode just destLen bytes. |
|
195 |
+ LZMA_FINISH_END - Stream must be finished after (*destLen). |
|
196 |
+*/ |
|
197 |
+ |
|
198 |
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, |
|
199 |
+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); |
|
200 |
+ |
|
201 |
+ |
|
202 |
+/* ---------- One Call Interface ---------- */ |
|
203 |
+ |
|
204 |
+/* LzmaDecode |
|
205 |
+ |
|
206 |
+finishMode: |
|
207 |
+ It has meaning only if the decoding reaches output limit (*destLen). |
|
208 |
+ LZMA_FINISH_ANY - Decode just destLen bytes. |
|
209 |
+ LZMA_FINISH_END - Stream must be finished after (*destLen). |
|
210 |
+ |
|
211 |
+Returns: |
|
212 |
+ SZ_OK |
|
213 |
+ status: |
|
214 |
+ LZMA_STATUS_FINISHED_WITH_MARK |
|
215 |
+ LZMA_STATUS_NOT_FINISHED |
|
216 |
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK |
|
217 |
+ SZ_ERROR_DATA - Data error |
|
218 |
+ SZ_ERROR_MEM - Memory allocation error |
|
219 |
+ SZ_ERROR_UNSUPPORTED - Unsupported properties |
|
220 |
+ SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). |
|
221 |
+*/ |
|
222 |
+ |
|
223 |
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, |
|
224 |
+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, |
|
225 |
+ ELzmaStatus *status, ISzAlloc *alloc); |
|
226 |
+ |
|
227 |
+#ifdef __cplusplus |
|
228 |
+} |
|
229 |
+#endif |
|
230 |
+ |
|
231 |
+#endif |
224 | 232 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,81 @@ |
0 |
+/* Ppmd.h -- PPMD codec common code |
|
1 |
+2010-03-12 : Igor Pavlov : Public domain |
|
2 |
+This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ |
|
3 |
+ |
|
4 |
+#ifndef __PPMD_H |
|
5 |
+#define __PPMD_H |
|
6 |
+ |
|
7 |
+#include "Types.h" |
|
8 |
+#include "CpuArch.h" |
|
9 |
+ |
|
10 |
+EXTERN_C_BEGIN |
|
11 |
+ |
|
12 |
+#ifdef MY_CPU_32BIT |
|
13 |
+ #define PPMD_32BIT |
|
14 |
+#endif |
|
15 |
+ |
|
16 |
+#define PPMD_INT_BITS 7 |
|
17 |
+#define PPMD_PERIOD_BITS 7 |
|
18 |
+#define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS)) |
|
19 |
+ |
|
20 |
+#define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift)) |
|
21 |
+#define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2) |
|
22 |
+#define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob)) |
|
23 |
+#define PPMD_UPDATE_PROB_1(prob) ((prob) - PPMD_GET_MEAN(prob)) |
|
24 |
+ |
|
25 |
+#define PPMD_N1 4 |
|
26 |
+#define PPMD_N2 4 |
|
27 |
+#define PPMD_N3 4 |
|
28 |
+#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4) |
|
29 |
+#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4) |
|
30 |
+ |
|
31 |
+/* SEE-contexts for PPM-contexts with masked symbols */ |
|
32 |
+typedef struct |
|
33 |
+{ |
|
34 |
+ UInt16 Summ; /* Freq */ |
|
35 |
+ Byte Shift; /* Speed of Freq change; low Shift is for fast change */ |
|
36 |
+ Byte Count; /* Count to next change of Shift */ |
|
37 |
+} CPpmd_See; |
|
38 |
+ |
|
39 |
+#define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \ |
|
40 |
+ { (p)->Summ <<= 1; (p)->Count = (Byte)(3 << (p)->Shift++); } |
|
41 |
+ |
|
42 |
+typedef struct |
|
43 |
+{ |
|
44 |
+ Byte Symbol; |
|
45 |
+ Byte Freq; |
|
46 |
+ UInt16 SuccessorLow; |
|
47 |
+ UInt16 SuccessorHigh; |
|
48 |
+} CPpmd_State; |
|
49 |
+ |
|
50 |
+typedef |
|
51 |
+ #ifdef PPMD_32BIT |
|
52 |
+ CPpmd_State * |
|
53 |
+ #else |
|
54 |
+ UInt32 |
|
55 |
+ #endif |
|
56 |
+ CPpmd_State_Ref; |
|
57 |
+ |
|
58 |
+typedef |
|
59 |
+ #ifdef PPMD_32BIT |
|
60 |
+ void * |
|
61 |
+ #else |
|
62 |
+ UInt32 |
|
63 |
+ #endif |
|
64 |
+ CPpmd_Void_Ref; |
|
65 |
+ |
|
66 |
+typedef |
|
67 |
+ #ifdef PPMD_32BIT |
|
68 |
+ Byte * |
|
69 |
+ #else |
|
70 |
+ UInt32 |
|
71 |
+ #endif |
|
72 |
+ CPpmd_Byte_Ref; |
|
73 |
+ |
|
74 |
+#define PPMD_SetAllBitsIn256Bytes(p) \ |
|
75 |
+ { unsigned i; for (i = 0; i < 256 / sizeof(p[0]); i += 8) { \ |
|
76 |
+ p[i+7] = p[i+6] = p[i+5] = p[i+4] = p[i+3] = p[i+2] = p[i+1] = p[i+0] = ~(size_t)0; }} |
|
77 |
+ |
|
78 |
+EXTERN_C_END |
|
79 |
+ |
|
80 |
+#endif |
0 | 81 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,708 @@ |
0 |
+/* Ppmd7.c -- PPMdH codec |
|
1 |
+2010-03-12 : Igor Pavlov : Public domain |
|
2 |
+This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ |
|
3 |
+ |
|
4 |
+#include <memory.h> |
|
5 |
+ |
|
6 |
+#include "Ppmd7.h" |
|
7 |
+ |
|
8 |
+const Byte PPMD7_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 }; |
|
9 |
+static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051}; |
|
10 |
+ |
|
11 |
+#define MAX_FREQ 124 |
|
12 |
+#define UNIT_SIZE 12 |
|
13 |
+ |
|
14 |
+#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE) |
|
15 |
+#define U2I(nu) (p->Units2Indx[(nu) - 1]) |
|
16 |
+#define I2U(indx) (p->Indx2Units[indx]) |
|
17 |
+ |
|
18 |
+#ifdef PPMD_32BIT |
|
19 |
+ #define REF(ptr) (ptr) |
|
20 |
+#else |
|
21 |
+ #define REF(ptr) ((UInt32)((Byte *)(ptr) - (p)->Base)) |
|
22 |
+#endif |
|
23 |
+ |
|
24 |
+#define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr)) |
|
25 |
+ |
|
26 |
+#define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref)) |
|
27 |
+#define STATS(ctx) Ppmd7_GetStats(p, ctx) |
|
28 |
+#define ONE_STATE(ctx) Ppmd7Context_OneState(ctx) |
|
29 |
+#define SUFFIX(ctx) CTX((ctx)->Suffix) |
|
30 |
+ |
|
31 |
+typedef CPpmd7_Context * CTX_PTR; |
|
32 |
+ |
|
33 |
+struct CPpmd7_Node_; |
|
34 |
+ |
|
35 |
+typedef |
|
36 |
+ #ifdef PPMD_32BIT |
|
37 |
+ struct CPpmd7_Node_ * |
|
38 |
+ #else |
|
39 |
+ UInt32 |
|
40 |
+ #endif |
|
41 |
+ CPpmd7_Node_Ref; |
|
42 |
+ |
|
43 |
+typedef struct CPpmd7_Node_ |
|
44 |
+{ |
|
45 |
+ UInt16 Stamp; /* must be at offset 0 as CPpmd7_Context::NumStats. Stamp=0 means free */ |
|
46 |
+ UInt16 NU; |
|
47 |
+ CPpmd7_Node_Ref Next; /* must be at offset >= 4 */ |
|
48 |
+ CPpmd7_Node_Ref Prev; |
|
49 |
+} CPpmd7_Node; |
|
50 |
+ |
|
51 |
+#ifdef PPMD_32BIT |
|
52 |
+ #define NODE(ptr) (ptr) |
|
53 |
+#else |
|
54 |
+ #define NODE(offs) ((CPpmd7_Node *)(p->Base + (offs))) |
|
55 |
+#endif |
|
56 |
+ |
|
57 |
+void Ppmd7_Construct(CPpmd7 *p) |
|
58 |
+{ |
|
59 |
+ unsigned i, k, m; |
|
60 |
+ |
|
61 |
+ p->Base = 0; |
|
62 |
+ |
|
63 |
+ for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++) |
|
64 |
+ { |
|
65 |
+ unsigned step = (i >= 12 ? 4 : (i >> 2) + 1); |
|
66 |
+ do { p->Units2Indx[k++] = (Byte)i; } while(--step); |
|
67 |
+ p->Indx2Units[i] = (Byte)k; |
|
68 |
+ } |
|
69 |
+ |
|
70 |
+ p->NS2BSIndx[0] = (0 << 1); |
|
71 |
+ p->NS2BSIndx[1] = (1 << 1); |
|
72 |
+ memset(p->NS2BSIndx + 2, (2 << 1), 9); |
|
73 |
+ memset(p->NS2BSIndx + 11, (3 << 1), 256 - 11); |
|
74 |
+ |
|
75 |
+ for (i = 0; i < 3; i++) |
|
76 |
+ p->NS2Indx[i] = (Byte)i; |
|
77 |
+ for (m = i, k = 1; i < 256; i++) |
|
78 |
+ { |
|
79 |
+ p->NS2Indx[i] = (Byte)m; |
|
80 |
+ if (--k == 0) |
|
81 |
+ k = (++m) - 2; |
|
82 |
+ } |
|
83 |
+ |
|
84 |
+ memset(p->HB2Flag, 0, 0x40); |
|
85 |
+ memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40); |
|
86 |
+} |
|
87 |
+ |
|
88 |
+void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc) |
|
89 |
+{ |
|
90 |
+ alloc->Free(alloc, p->Base); |
|
91 |
+ p->Size = 0; |
|
92 |
+ p->Base = 0; |
|
93 |
+} |
|
94 |
+ |
|
95 |
+Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc) |
|
96 |
+{ |
|
97 |
+ if (p->Base == 0 || p->Size != size) |
|
98 |
+ { |
|
99 |
+ Ppmd7_Free(p, alloc); |
|
100 |
+ p->AlignOffset = |
|
101 |
+ #ifdef PPMD_32BIT |
|
102 |
+ (4 - size) & 3; |
|
103 |
+ #else |
|
104 |
+ 4 - (size & 3); |
|
105 |
+ #endif |
|
106 |
+ if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size |
|
107 |
+ #ifndef PPMD_32BIT |
|
108 |
+ + UNIT_SIZE |
|
109 |
+ #endif |
|
110 |
+ )) == 0) |
|
111 |
+ return False; |
|
112 |
+ p->Size = size; |
|
113 |
+ } |
|
114 |
+ return True; |
|
115 |
+} |
|
116 |
+ |
|
117 |
+static void InsertNode(CPpmd7 *p, void *node, unsigned indx) |
|
118 |
+{ |
|
119 |
+ *((CPpmd_Void_Ref *)node) = p->FreeList[indx]; |
|
120 |
+ p->FreeList[indx] = REF(node); |
|
121 |
+} |
|
122 |
+ |
|
123 |
+static void *RemoveNode(CPpmd7 *p, unsigned indx) |
|
124 |
+{ |
|
125 |
+ CPpmd_Void_Ref *node = (CPpmd_Void_Ref *)Ppmd7_GetPtr(p, p->FreeList[indx]); |
|
126 |
+ p->FreeList[indx] = *node; |
|
127 |
+ return node; |
|
128 |
+} |
|
129 |
+ |
|
130 |
+static void SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx) |
|
131 |
+{ |
|
132 |
+ unsigned i, nu = I2U(oldIndx) - I2U(newIndx); |
|
133 |
+ ptr = (Byte *)ptr + U2B(I2U(newIndx)); |
|
134 |
+ if (I2U(i = U2I(nu)) != nu) |
|
135 |
+ { |
|
136 |
+ unsigned k = I2U(--i); |
|
137 |
+ InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1); |
|
138 |
+ } |
|
139 |
+ InsertNode(p, ptr, i); |
|
140 |
+} |
|
141 |
+ |
|
142 |
+static void GlueFreeBlocks(CPpmd7 *p) |
|
143 |
+{ |
|
144 |
+ #ifdef PPMD_32BIT |
|
145 |
+ CPpmd7_Node headItem; |
|
146 |
+ CPpmd7_Node_Ref head = &headItem; |
|
147 |
+ #else |
|
148 |
+ CPpmd7_Node_Ref head = p->AlignOffset + p->Size; |
|
149 |
+ #endif |
|
150 |
+ |
|
151 |
+ CPpmd7_Node_Ref n = head; |
|
152 |
+ unsigned i; |
|
153 |
+ |
|
154 |
+ p->GlueCount = 255; |
|
155 |
+ |
|
156 |
+ /* create doubly-linked list of free blocks */ |
|
157 |
+ for (i = 0; i < PPMD_NUM_INDEXES; i++) |
|
158 |
+ { |
|
159 |
+ UInt16 nu = I2U(i); |
|
160 |
+ CPpmd7_Node_Ref next = (CPpmd7_Node_Ref)p->FreeList[i]; |
|
161 |
+ p->FreeList[i] = 0; |
|
162 |
+ while (next != 0) |
|
163 |
+ { |
|
164 |
+ CPpmd7_Node *node = NODE(next); |
|
165 |
+ node->Next = n; |
|
166 |
+ n = NODE(n)->Prev = next; |
|
167 |
+ next = *(const CPpmd7_Node_Ref *)node; |
|
168 |
+ node->Stamp = 0; |
|
169 |
+ node->NU = (UInt16)nu; |
|
170 |
+ } |
|
171 |
+ } |
|
172 |
+ NODE(head)->Stamp = 1; |
|
173 |
+ NODE(head)->Next = n; |
|
174 |
+ NODE(n)->Prev = head; |
|
175 |
+ if (p->LoUnit != p->HiUnit) |
|
176 |
+ ((CPpmd7_Node *)p->LoUnit)->Stamp = 1; |
|
177 |
+ |
|
178 |
+ /* Glue free blocks */ |
|
179 |
+ while (n != head) |
|
180 |
+ { |
|
181 |
+ CPpmd7_Node *node = NODE(n); |
|
182 |
+ UInt32 nu = (UInt32)node->NU; |
|
183 |
+ for (;;) |
|
184 |
+ { |
|
185 |
+ CPpmd7_Node *node2 = NODE(n) + nu; |
|
186 |
+ nu += node2->NU; |
|
187 |
+ if (node2->Stamp != 0 || nu >= 0x10000) |
|
188 |
+ break; |
|
189 |
+ NODE(node2->Prev)->Next = node2->Next; |
|
190 |
+ NODE(node2->Next)->Prev = node2->Prev; |
|
191 |
+ node->NU = (UInt16)nu; |
|
192 |
+ } |
|
193 |
+ n = node->Next; |
|
194 |
+ } |
|
195 |
+ |
|
196 |
+ /* Fill lists of free blocks */ |
|
197 |
+ for (n = NODE(head)->Next; n != head;) |
|
198 |
+ { |
|
199 |
+ CPpmd7_Node *node = NODE(n); |
|
200 |
+ unsigned nu; |
|
201 |
+ CPpmd7_Node_Ref next = node->Next; |
|
202 |
+ for (nu = node->NU; nu > 128; nu -= 128, node += 128) |
|
203 |
+ InsertNode(p, node, PPMD_NUM_INDEXES - 1); |
|
204 |
+ if (I2U(i = U2I(nu)) != nu) |
|
205 |
+ { |
|
206 |
+ unsigned k = I2U(--i); |
|
207 |
+ InsertNode(p, node + k, nu - k - 1); |
|
208 |
+ } |
|
209 |
+ InsertNode(p, node, i); |
|
210 |
+ n = next; |
|
211 |
+ } |
|
212 |
+} |
|
213 |
+ |
|
214 |
+static void *AllocUnitsRare(CPpmd7 *p, unsigned indx) |
|
215 |
+{ |
|
216 |
+ unsigned i; |
|
217 |
+ void *retVal; |
|
218 |
+ if (p->GlueCount == 0) |
|
219 |
+ { |
|
220 |
+ GlueFreeBlocks(p); |
|
221 |
+ if (p->FreeList[indx] != 0) |
|
222 |
+ return RemoveNode(p, indx); |
|
223 |
+ } |
|
224 |
+ i = indx; |
|
225 |
+ do |
|
226 |
+ { |
|
227 |
+ if (++i == PPMD_NUM_INDEXES) |
|
228 |
+ { |
|
229 |
+ UInt32 numBytes = U2B(I2U(indx)); |
|
230 |
+ p->GlueCount--; |
|
231 |
+ return ((UInt32)(p->UnitsStart - p->Text) > numBytes) ? (p->UnitsStart -= numBytes) : (NULL); |
|
232 |
+ } |
|
233 |
+ } |
|
234 |
+ while (p->FreeList[i] == 0); |
|
235 |
+ retVal = RemoveNode(p, i); |
|
236 |
+ SplitBlock(p, retVal, i, indx); |
|
237 |
+ return retVal; |
|
238 |
+} |
|
239 |
+ |
|
240 |
+static void *AllocUnits(CPpmd7 *p, unsigned indx) |
|
241 |
+{ |
|
242 |
+ UInt32 numBytes; |
|
243 |
+ if (p->FreeList[indx] != 0) |
|
244 |
+ return RemoveNode(p, indx); |
|
245 |
+ numBytes = U2B(I2U(indx)); |
|
246 |
+ if (numBytes <= (UInt32)(p->HiUnit - p->LoUnit)) |
|
247 |
+ { |
|
248 |
+ void *retVal = p->LoUnit; |
|
249 |
+ p->LoUnit += numBytes; |
|
250 |
+ return retVal; |
|
251 |
+ } |
|
252 |
+ return AllocUnitsRare(p, indx); |
|
253 |
+} |
|
254 |
+ |
|
255 |
+#define MyMem12Cpy(dest, src, num) \ |
|
256 |
+ { UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \ |
|
257 |
+ do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); } |
|
258 |
+ |
|
259 |
+static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU) |
|
260 |
+{ |
|
261 |
+ unsigned i0 = U2I(oldNU); |
|
262 |
+ unsigned i1 = U2I(newNU); |
|
263 |
+ if (i0 == i1) |
|
264 |
+ return oldPtr; |
|
265 |
+ if (p->FreeList[i1] != 0) |
|
266 |
+ { |
|
267 |
+ void *ptr = RemoveNode(p, i1); |
|
268 |
+ MyMem12Cpy(ptr, oldPtr, newNU); |
|
269 |
+ InsertNode(p, oldPtr, i0); |
|
270 |
+ return ptr; |
|
271 |
+ } |
|
272 |
+ SplitBlock(p, oldPtr, i0, i1); |
|
273 |
+ return oldPtr; |
|
274 |
+} |
|
275 |
+ |
|
276 |
+#define SUCCESSOR(p) ((CPpmd_Void_Ref)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16))) |
|
277 |
+ |
|
278 |
+static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v) |
|
279 |
+{ |
|
280 |
+ (p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF); |
|
281 |
+ (p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF); |
|
282 |
+} |
|
283 |
+ |
|
284 |
+static void RestartModel(CPpmd7 *p) |
|
285 |
+{ |
|
286 |
+ unsigned i, k, m; |
|
287 |
+ |
|
288 |
+ memset(p->FreeList, 0, sizeof(p->FreeList)); |
|
289 |
+ p->Text = p->Base + p->AlignOffset; |
|
290 |
+ p->HiUnit = p->Text + p->Size; |
|
291 |
+ p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE; |
|
292 |
+ p->GlueCount = 0; |
|
293 |
+ |
|
294 |
+ p->OrderFall = p->MaxOrder; |
|
295 |
+ p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1; |
|
296 |
+ p->PrevSuccess = 0; |
|
297 |
+ |
|
298 |
+ p->MinContext = p->MaxContext = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */ |
|
299 |
+ p->MinContext->Suffix = 0; |
|
300 |
+ p->MinContext->NumStats = 256; |
|
301 |
+ p->MinContext->SummFreq = 256 + 1; |
|
302 |
+ p->FoundState = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */ |
|
303 |
+ p->LoUnit += U2B(256 / 2); |
|
304 |
+ p->MinContext->Stats = REF(p->FoundState); |
|
305 |
+ for (i = 0; i < 256; i++) |
|
306 |
+ { |
|
307 |
+ CPpmd_State *s = &p->FoundState[i]; |
|
308 |
+ s->Symbol = (Byte)i; |
|
309 |
+ s->Freq = 1; |
|
310 |
+ SetSuccessor(s, 0); |
|
311 |
+ } |
|
312 |
+ |
|
313 |
+ for (i = 0; i < 128; i++) |
|
314 |
+ for (k = 0; k < 8; k++) |
|
315 |
+ { |
|
316 |
+ UInt16 *dest = p->BinSumm[i] + k; |
|
317 |
+ UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2)); |
|
318 |
+ for (m = 0; m < 64; m += 8) |
|
319 |
+ dest[m] = val; |
|
320 |
+ } |
|
321 |
+ |
|
322 |
+ for (i = 0; i < 25; i++) |
|
323 |
+ for (k = 0; k < 16; k++) |
|
324 |
+ { |
|
325 |
+ CPpmd_See *s = &p->See[i][k]; |
|
326 |
+ s->Summ = (UInt16)((5 * i + 10) << (s->Shift = PPMD_PERIOD_BITS - 4)); |
|
327 |
+ s->Count = 4; |
|
328 |
+ } |
|
329 |
+} |
|
330 |
+ |
|
331 |
+void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder) |
|
332 |
+{ |
|
333 |
+ p->MaxOrder = maxOrder; |
|
334 |
+ RestartModel(p); |
|
335 |
+ p->DummySee.Shift = PPMD_PERIOD_BITS; |
|
336 |
+ p->DummySee.Summ = 0; /* unused */ |
|
337 |
+ p->DummySee.Count = 64; /* unused */ |
|
338 |
+} |
|
339 |
+ |
|
340 |
+static CTX_PTR CreateSuccessors(CPpmd7 *p, Bool skip) |
|
341 |
+{ |
|
342 |
+ CPpmd_State upState; |
|
343 |
+ CTX_PTR c = p->MinContext; |
|
344 |
+ CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState); |
|
345 |
+ CPpmd_State *ps[PPMD7_MAX_ORDER]; |
|
346 |
+ unsigned numPs = 0; |
|
347 |
+ |
|
348 |
+ if (!skip) |
|
349 |
+ ps[numPs++] = p->FoundState; |
|
350 |
+ |
|
351 |
+ while (c->Suffix) |
|
352 |
+ { |
|
353 |
+ CPpmd_Void_Ref successor; |
|
354 |
+ CPpmd_State *s; |
|
355 |
+ c = SUFFIX(c); |
|
356 |
+ if (c->NumStats != 1) |
|
357 |
+ { |
|
358 |
+ for (s = STATS(c); s->Symbol != p->FoundState->Symbol; s++); |
|
359 |
+ } |
|
360 |
+ else |
|
361 |
+ s = ONE_STATE(c); |
|
362 |
+ successor = SUCCESSOR(s); |
|
363 |
+ if (successor != upBranch) |
|
364 |
+ { |
|
365 |
+ c = CTX(successor); |
|
366 |
+ if (numPs == 0) |
|
367 |
+ return c; |
|
368 |
+ break; |
|
369 |
+ } |
|
370 |
+ ps[numPs++] = s; |
|
371 |
+ } |
|
372 |
+ |
|
373 |
+ upState.Symbol = *(const Byte *)Ppmd7_GetPtr(p, upBranch); |
|
374 |
+ SetSuccessor(&upState, upBranch + 1); |
|
375 |
+ |
|
376 |
+ if (c->NumStats == 1) |
|
377 |
+ upState.Freq = ONE_STATE(c)->Freq; |
|
378 |
+ else |
|
379 |
+ { |
|
380 |
+ UInt32 cf, s0; |
|
381 |
+ CPpmd_State *s; |
|
382 |
+ for (s = STATS(c); s->Symbol != upState.Symbol; s++); |
|
383 |
+ cf = s->Freq - 1; |
|
384 |
+ s0 = c->SummFreq - c->NumStats - cf; |
|
385 |
+ upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((2 * cf + 3 * s0 - 1) / (2 * s0)))); |
|
386 |
+ } |
|
387 |
+ |
|
388 |
+ do |
|
389 |
+ { |
|
390 |
+ /* Create Child */ |
|
391 |
+ CTX_PTR c1; /* = AllocContext(p); */ |
|
392 |
+ if (p->HiUnit != p->LoUnit) |
|
393 |
+ c1 = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); |
|
394 |
+ else if (p->FreeList[0] != 0) |
|
395 |
+ c1 = (CTX_PTR)RemoveNode(p, 0); |
|
396 |
+ else |
|
397 |
+ { |
|
398 |
+ c1 = (CTX_PTR)AllocUnitsRare(p, 0); |
|
399 |
+ if (!c1) |
|
400 |
+ return NULL; |
|
401 |
+ } |
|
402 |
+ c1->NumStats = 1; |
|
403 |
+ *ONE_STATE(c1) = upState; |
|
404 |
+ c1->Suffix = REF(c); |
|
405 |
+ SetSuccessor(ps[--numPs], REF(c1)); |
|
406 |
+ c = c1; |
|
407 |
+ } |
|
408 |
+ while (numPs != 0); |
|
409 |
+ |
|
410 |
+ return c; |
|
411 |
+} |
|
412 |
+ |
|
413 |
+static void SwapStates(CPpmd_State *t1, CPpmd_State *t2) |
|
414 |
+{ |
|
415 |
+ CPpmd_State tmp = *t1; |
|
416 |
+ *t1 = *t2; |
|
417 |
+ *t2 = tmp; |
|
418 |
+} |
|
419 |
+ |
|
420 |
+static void UpdateModel(CPpmd7 *p) |
|
421 |
+{ |
|
422 |
+ CPpmd_Void_Ref successor, fSuccessor = SUCCESSOR(p->FoundState); |
|
423 |
+ CTX_PTR c; |
|
424 |
+ unsigned s0, ns; |
|
425 |
+ |
|
426 |
+ if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0) |
|
427 |
+ { |
|
428 |
+ c = SUFFIX(p->MinContext); |
|
429 |
+ |
|
430 |
+ if (c->NumStats == 1) |
|
431 |
+ { |
|
432 |
+ CPpmd_State *s = ONE_STATE(c); |
|
433 |
+ if (s->Freq < 32) |
|
434 |
+ s->Freq++; |
|
435 |
+ } |
|
436 |
+ else |
|
437 |
+ { |
|
438 |
+ CPpmd_State *s = STATS(c); |
|
439 |
+ if (s->Symbol != p->FoundState->Symbol) |
|
440 |
+ { |
|
441 |
+ do { s++; } while (s->Symbol != p->FoundState->Symbol); |
|
442 |
+ if (s[0].Freq >= s[-1].Freq) |
|
443 |
+ { |
|
444 |
+ SwapStates(&s[0], &s[-1]); |
|
445 |
+ s--; |
|
446 |
+ } |
|
447 |
+ } |
|
448 |
+ if (s->Freq < MAX_FREQ - 9) |
|
449 |
+ { |
|
450 |
+ s->Freq += 2; |
|
451 |
+ c->SummFreq += 2; |
|
452 |
+ } |
|
453 |
+ } |
|
454 |
+ } |
|
455 |
+ |
|
456 |
+ if (p->OrderFall == 0) |
|
457 |
+ { |
|
458 |
+ p->MinContext = p->MaxContext = CreateSuccessors(p, True); |
|
459 |
+ if (p->MinContext == 0) |
|
460 |
+ { |
|
461 |
+ RestartModel(p); |
|
462 |
+ return; |
|
463 |
+ } |
|
464 |
+ SetSuccessor(p->FoundState, REF(p->MinContext)); |
|
465 |
+ return; |
|
466 |
+ } |
|
467 |
+ |
|
468 |
+ *p->Text++ = p->FoundState->Symbol; |
|
469 |
+ successor = REF(p->Text); |
|
470 |
+ if (p->Text >= p->UnitsStart) |
|
471 |
+ { |
|
472 |
+ RestartModel(p); |
|
473 |
+ return; |
|
474 |
+ } |
|
475 |
+ |
|
476 |
+ if (fSuccessor) |
|
477 |
+ { |
|
478 |
+ if (fSuccessor <= successor) |
|
479 |
+ { |
|
480 |
+ CTX_PTR cs = CreateSuccessors(p, False); |
|
481 |
+ if (cs == NULL) |
|
482 |
+ { |
|
483 |
+ RestartModel(p); |
|
484 |
+ return; |
|
485 |
+ } |
|
486 |
+ fSuccessor = REF(cs); |
|
487 |
+ } |
|
488 |
+ if (--p->OrderFall == 0) |
|
489 |
+ { |
|
490 |
+ successor = fSuccessor; |
|
491 |
+ p->Text -= (p->MaxContext != p->MinContext); |
|
492 |
+ } |
|
493 |
+ } |
|
494 |
+ else |
|
495 |
+ { |
|
496 |
+ SetSuccessor(p->FoundState, successor); |
|
497 |
+ fSuccessor = REF(p->MinContext); |
|
498 |
+ } |
|
499 |
+ |
|
500 |
+ s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - (p->FoundState->Freq - 1); |
|
501 |
+ |
|
502 |
+ for (c = p->MaxContext; c != p->MinContext; c = SUFFIX(c)) |
|
503 |
+ { |
|
504 |
+ unsigned ns1; |
|
505 |
+ UInt32 cf, sf; |
|
506 |
+ if ((ns1 = c->NumStats) != 1) |
|
507 |
+ { |
|
508 |
+ if ((ns1 & 1) == 0) |
|
509 |
+ { |
|
510 |
+ /* Expand for one UNIT */ |
|
511 |
+ unsigned oldNU = ns1 >> 1; |
|
512 |
+ unsigned i = U2I(oldNU); |
|
513 |
+ if (i != U2I(oldNU + 1)) |
|
514 |
+ { |
|
515 |
+ void *ptr = AllocUnits(p, i + 1); |
|
516 |
+ void *oldPtr; |
|
517 |
+ if (!ptr) |
|
518 |
+ { |
|
519 |
+ RestartModel(p); |
|
520 |
+ return; |
|
521 |
+ } |
|
522 |
+ oldPtr = STATS(c); |
|
523 |
+ MyMem12Cpy(ptr, oldPtr, oldNU); |
|
524 |
+ InsertNode(p, oldPtr, i); |
|
525 |
+ c->Stats = STATS_REF(ptr); |
|
526 |
+ } |
|
527 |
+ } |
|
528 |
+ c->SummFreq = (UInt16)(c->SummFreq + (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) & (c->SummFreq <= 8 * ns1))); |
|
529 |
+ } |
|
530 |
+ else |
|
531 |
+ { |
|
532 |
+ CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0); |
|
533 |
+ if (!s) |
|
534 |
+ { |
|
535 |
+ RestartModel(p); |
|
536 |
+ return; |
|
537 |
+ } |
|
538 |
+ *s = *ONE_STATE(c); |
|
539 |
+ c->Stats = REF(s); |
|
540 |
+ if (s->Freq < MAX_FREQ / 4 - 1) |
|
541 |
+ s->Freq <<= 1; |
|
542 |
+ else |
|
543 |
+ s->Freq = MAX_FREQ - 4; |
|
544 |
+ c->SummFreq = (UInt16)(s->Freq + p->InitEsc + (ns > 3)); |
|
545 |
+ } |
|
546 |
+ cf = 2 * (UInt32)p->FoundState->Freq * (c->SummFreq + 6); |
|
547 |
+ sf = (UInt32)s0 + c->SummFreq; |
|
548 |
+ if (cf < 6 * sf) |
|
549 |
+ { |
|
550 |
+ cf = 1 + (cf > sf) + (cf >= 4 * sf); |
|
551 |
+ c->SummFreq += 3; |
|
552 |
+ } |
|
553 |
+ else |
|
554 |
+ { |
|
555 |
+ cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf); |
|
556 |
+ c->SummFreq = (UInt16)(c->SummFreq + cf); |
|
557 |
+ } |
|
558 |
+ { |
|
559 |
+ CPpmd_State *s = STATS(c) + ns1; |
|
560 |
+ SetSuccessor(s, successor); |
|
561 |
+ s->Symbol = p->FoundState->Symbol; |
|
562 |
+ s->Freq = (Byte)cf; |
|
563 |
+ c->NumStats = (UInt16)(ns1 + 1); |
|
564 |
+ } |
|
565 |
+ } |
|
566 |
+ p->MaxContext = p->MinContext = CTX(fSuccessor); |
|
567 |
+} |
|
568 |
+ |
|
569 |
+static void Rescale(CPpmd7 *p) |
|
570 |
+{ |
|
571 |
+ unsigned i, adder, sumFreq, escFreq; |
|
572 |
+ CPpmd_State *stats = STATS(p->MinContext); |
|
573 |
+ CPpmd_State *s = p->FoundState; |
|
574 |
+ { |
|
575 |
+ CPpmd_State tmp = *s; |
|
576 |
+ for (; s != stats; s--) |
|
577 |
+ s[0] = s[-1]; |
|
578 |
+ *s = tmp; |
|
579 |
+ } |
|
580 |
+ escFreq = p->MinContext->SummFreq - s->Freq; |
|
581 |
+ s->Freq += 4; |
|
582 |
+ adder = (p->OrderFall != 0); |
|
583 |
+ s->Freq = (Byte)((s->Freq + adder) >> 1); |
|
584 |
+ sumFreq = s->Freq; |
|
585 |
+ |
|
586 |
+ i = p->MinContext->NumStats - 1; |
|
587 |
+ do |
|
588 |
+ { |
|
589 |
+ escFreq -= (++s)->Freq; |
|
590 |
+ s->Freq = (Byte)((s->Freq + adder) >> 1); |
|
591 |
+ sumFreq += s->Freq; |
|
592 |
+ if (s[0].Freq > s[-1].Freq) |
|
593 |
+ { |
|
594 |
+ CPpmd_State *s1 = s; |
|
595 |
+ CPpmd_State tmp = *s1; |
|
596 |
+ do |
|
597 |
+ s1[0] = s1[-1]; |
|
598 |
+ while (--s1 != stats && tmp.Freq > s1[-1].Freq); |
|
599 |
+ *s1 = tmp; |
|
600 |
+ } |
|
601 |
+ } |
|
602 |
+ while (--i); |
|
603 |
+ |
|
604 |
+ if (s->Freq == 0) |
|
605 |
+ { |
|
606 |
+ unsigned numStats = p->MinContext->NumStats; |
|
607 |
+ unsigned n0, n1; |
|
608 |
+ do { i++; } while ((--s)->Freq == 0); |
|
609 |
+ escFreq += i; |
|
610 |
+ p->MinContext->NumStats = (UInt16)(p->MinContext->NumStats - i); |
|
611 |
+ if (p->MinContext->NumStats == 1) |
|
612 |
+ { |
|
613 |
+ CPpmd_State tmp = *stats; |
|
614 |
+ do |
|
615 |
+ { |
|
616 |
+ tmp.Freq = (Byte)(tmp.Freq - (tmp.Freq >> 1)); |
|
617 |
+ escFreq >>= 1; |
|
618 |
+ } |
|
619 |
+ while (escFreq > 1); |
|
620 |
+ InsertNode(p, stats, U2I(((numStats + 1) >> 1))); |
|
621 |
+ *(p->FoundState = ONE_STATE(p->MinContext)) = tmp; |
|
622 |
+ return; |
|
623 |
+ } |
|
624 |
+ n0 = (numStats + 1) >> 1; |
|
625 |
+ n1 = (p->MinContext->NumStats + 1) >> 1; |
|
626 |
+ if (n0 != n1) |
|
627 |
+ p->MinContext->Stats = STATS_REF(ShrinkUnits(p, stats, n0, n1)); |
|
628 |
+ } |
|
629 |
+ p->MinContext->SummFreq = (UInt16)(sumFreq + escFreq - (escFreq >> 1)); |
|
630 |
+ p->FoundState = STATS(p->MinContext); |
|
631 |
+} |
|
632 |
+ |
|
633 |
+CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq) |
|
634 |
+{ |
|
635 |
+ CPpmd_See *see; |
|
636 |
+ unsigned nonMasked = p->MinContext->NumStats - numMasked; |
|
637 |
+ if (p->MinContext->NumStats != 256) |
|
638 |
+ { |
|
639 |
+ see = p->See[p->NS2Indx[nonMasked - 1]] + |
|
640 |
+ (nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) + |
|
641 |
+ 2 * (p->MinContext->SummFreq < 11 * p->MinContext->NumStats) + |
|
642 |
+ 4 * (numMasked > nonMasked) + |
|
643 |
+ p->HiBitsFlag; |
|
644 |
+ { |
|
645 |
+ unsigned r = (see->Summ >> see->Shift); |
|
646 |
+ see->Summ = (UInt16)(see->Summ - r); |
|
647 |
+ *escFreq = r + (r == 0); |
|
648 |
+ } |
|
649 |
+ } |
|
650 |
+ else |
|
651 |
+ { |
|
652 |
+ see = &p->DummySee; |
|
653 |
+ *escFreq = 1; |
|
654 |
+ } |
|
655 |
+ return see; |
|
656 |
+} |
|
657 |
+ |
|
658 |
+static void NextContext(CPpmd7 *p) |
|
659 |
+{ |
|
660 |
+ CTX_PTR c = CTX(SUCCESSOR(p->FoundState)); |
|
661 |
+ if (p->OrderFall == 0 && (Byte *)c > p->Text) |
|
662 |
+ p->MinContext = p->MaxContext = c; |
|
663 |
+ else |
|
664 |
+ UpdateModel(p); |
|
665 |
+} |
|
666 |
+ |
|
667 |
+void Ppmd7_Update1(CPpmd7 *p) |
|
668 |
+{ |
|
669 |
+ CPpmd_State *s = p->FoundState; |
|
670 |
+ s->Freq += 4; |
|
671 |
+ p->MinContext->SummFreq += 4; |
|
672 |
+ if (s[0].Freq > s[-1].Freq) |
|
673 |
+ { |
|
674 |
+ SwapStates(&s[0], &s[-1]); |
|
675 |
+ p->FoundState = --s; |
|
676 |
+ if (s->Freq > MAX_FREQ) |
|
677 |
+ Rescale(p); |
|
678 |
+ } |
|
679 |
+ NextContext(p); |
|
680 |
+} |
|
681 |
+ |
|
682 |
+void Ppmd7_Update1_0(CPpmd7 *p) |
|
683 |
+{ |
|
684 |
+ p->PrevSuccess = (2 * p->FoundState->Freq > p->MinContext->SummFreq); |
|
685 |
+ p->RunLength += p->PrevSuccess; |
|
686 |
+ p->MinContext->SummFreq += 4; |
|
687 |
+ if ((p->FoundState->Freq += 4) > MAX_FREQ) |
|
688 |
+ Rescale(p); |
|
689 |
+ NextContext(p); |
|
690 |
+} |
|
691 |
+ |
|
692 |
+void Ppmd7_UpdateBin(CPpmd7 *p) |
|
693 |
+{ |
|
694 |
+ p->FoundState->Freq = (Byte)(p->FoundState->Freq + (p->FoundState->Freq < 128 ? 1: 0)); |
|
695 |
+ p->PrevSuccess = 1; |
|
696 |
+ p->RunLength++; |
|
697 |
+ NextContext(p); |
|
698 |
+} |
|
699 |
+ |
|
700 |
+void Ppmd7_Update2(CPpmd7 *p) |
|
701 |
+{ |
|
702 |
+ p->MinContext->SummFreq += 4; |
|
703 |
+ if ((p->FoundState->Freq += 4) > MAX_FREQ) |
|
704 |
+ Rescale(p); |
|
705 |
+ p->RunLength = p->InitRL; |
|
706 |
+ UpdateModel(p); |
|
707 |
+} |
0 | 708 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,140 @@ |
0 |
+/* Ppmd7.h -- PPMdH compression codec |
|
1 |
+2010-03-12 : Igor Pavlov : Public domain |
|
2 |
+This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ |
|
3 |
+ |
|
4 |
+/* This code supports virtual RangeDecoder and includes the implementation |
|
5 |
+of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H. |
|
6 |
+If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */ |
|
7 |
+ |
|
8 |
+#ifndef __PPMD7_H |
|
9 |
+#define __PPMD7_H |
|
10 |
+ |
|
11 |
+#include "Ppmd.h" |
|
12 |
+ |
|
13 |
+EXTERN_C_BEGIN |
|
14 |
+ |
|
15 |
+#define PPMD7_MIN_ORDER 2 |
|
16 |
+#define PPMD7_MAX_ORDER 64 |
|
17 |
+ |
|
18 |
+#define PPMD7_MIN_MEM_SIZE (1 << 11) |
|
19 |
+#define PPMD7_MAX_MEM_SIZE (0xFFFFFFFF - 12 * 3) |
|
20 |
+ |
|
21 |
+struct CPpmd7_Context_; |
|
22 |
+ |
|
23 |
+typedef |
|
24 |
+ #ifdef PPMD_32BIT |
|
25 |
+ struct CPpmd7_Context_ * |
|
26 |
+ #else |
|
27 |
+ UInt32 |
|
28 |
+ #endif |
|
29 |
+ CPpmd7_Context_Ref; |
|
30 |
+ |
|
31 |
+typedef struct CPpmd7_Context_ |
|
32 |
+{ |
|
33 |
+ UInt16 NumStats; |
|
34 |
+ UInt16 SummFreq; |
|
35 |
+ CPpmd_State_Ref Stats; |
|
36 |
+ CPpmd7_Context_Ref Suffix; |
|
37 |
+} CPpmd7_Context; |
|
38 |
+ |
|
39 |
+#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq) |
|
40 |
+ |
|
41 |
+typedef struct |
|
42 |
+{ |
|
43 |
+ CPpmd7_Context *MinContext, *MaxContext; |
|
44 |
+ CPpmd_State *FoundState; |
|
45 |
+ unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag; |
|
46 |
+ Int32 RunLength, InitRL; /* must be 32-bit at least */ |
|
47 |
+ |
|
48 |
+ UInt32 Size; |
|
49 |
+ UInt32 GlueCount; |
|
50 |
+ Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart; |
|
51 |
+ UInt32 AlignOffset; |
|
52 |
+ |
|
53 |
+ Byte Indx2Units[PPMD_NUM_INDEXES]; |
|
54 |
+ Byte Units2Indx[128]; |
|
55 |
+ CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES]; |
|
56 |
+ Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256]; |
|
57 |
+ CPpmd_See DummySee, See[25][16]; |
|
58 |
+ UInt16 BinSumm[128][64]; |
|
59 |
+} CPpmd7; |
|
60 |
+ |
|
61 |
+void Ppmd7_Construct(CPpmd7 *p); |
|
62 |
+Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc); |
|
63 |
+void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc); |
|
64 |
+void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder); |
|
65 |
+#define Ppmd7_WasAllocated(p) ((p)->Base != NULL) |
|
66 |
+ |
|
67 |
+ |
|
68 |
+/* ---------- Internal Functions ---------- */ |
|
69 |
+ |
|
70 |
+extern const Byte PPMD7_kExpEscape[16]; |
|
71 |
+ |
|
72 |
+#ifdef PPMD_32BIT |
|
73 |
+ #define Ppmd7_GetPtr(p, ptr) (ptr) |
|
74 |
+ #define Ppmd7_GetContext(p, ptr) (ptr) |
|
75 |
+ #define Ppmd7_GetStats(p, ctx) ((ctx)->Stats) |
|
76 |
+#else |
|
77 |
+ #define Ppmd7_GetPtr(p, offs) ((void *)((p)->Base + (offs))) |
|
78 |
+ #define Ppmd7_GetContext(p, offs) ((CPpmd7_Context *)Ppmd7_GetPtr((p), (offs))) |
|
79 |
+ #define Ppmd7_GetStats(p, ctx) ((CPpmd_State *)Ppmd7_GetPtr((p), ((ctx)->Stats))) |
|
80 |
+#endif |
|
81 |
+ |
|
82 |
+void Ppmd7_Update1(CPpmd7 *p); |
|
83 |
+void Ppmd7_Update1_0(CPpmd7 *p); |
|
84 |
+void Ppmd7_Update2(CPpmd7 *p); |
|
85 |
+void Ppmd7_UpdateBin(CPpmd7 *p); |
|
86 |
+ |
|
87 |
+#define Ppmd7_GetBinSumm(p) \ |
|
88 |
+ &p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \ |
|
89 |
+ p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \ |
|
90 |
+ (p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \ |
|
91 |
+ 2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \ |
|
92 |
+ ((p->RunLength >> 26) & 0x20)] |
|
93 |
+ |
|
94 |
+CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale); |
|
95 |
+ |
|
96 |
+ |
|
97 |
+/* ---------- Decode ---------- */ |
|
98 |
+ |
|
99 |
+typedef struct |
|
100 |
+{ |
|
101 |
+ UInt32 (*GetThreshold)(void *p, UInt32 total); |
|
102 |
+ void (*Decode)(void *p, UInt32 start, UInt32 size); |
|
103 |
+ UInt32 (*DecodeBit)(void *p, UInt32 size0); |
|
104 |
+} IPpmd7_RangeDec; |
|
105 |
+ |
|
106 |
+typedef struct |
|
107 |
+{ |
|
108 |
+ IPpmd7_RangeDec p; |
|
109 |
+ UInt32 Range; |
|
110 |
+ UInt32 Code; |
|
111 |
+ IByteIn *Stream; |
|
112 |
+} CPpmd7z_RangeDec; |
|
113 |
+ |
|
114 |
+void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p); |
|
115 |
+Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p); |
|
116 |
+#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0) |
|
117 |
+ |
|
118 |
+int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc); |
|
119 |
+ |
|
120 |
+ |
|
121 |
+/* ---------- Encode ---------- */ |
|
122 |
+ |
|
123 |
+typedef struct |
|
124 |
+{ |
|
125 |
+ UInt64 Low; |
|
126 |
+ UInt32 Range; |
|
127 |
+ Byte Cache; |
|
128 |
+ UInt64 CacheSize; |
|
129 |
+ IByteOut *Stream; |
|
130 |
+} CPpmd7z_RangeEnc; |
|
131 |
+ |
|
132 |
+void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p); |
|
133 |
+void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p); |
|
134 |
+ |
|
135 |
+void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol); |
|
136 |
+ |
|
137 |
+EXTERN_C_END |
|
138 |
+ |
|
139 |
+#endif |
0 | 140 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,187 @@ |
0 |
+/* Ppmd7Dec.c -- PPMdH Decoder |
|
1 |
+2010-03-12 : Igor Pavlov : Public domain |
|
2 |
+This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ |
|
3 |
+ |
|
4 |
+#include "Ppmd7.h" |
|
5 |
+ |
|
6 |
+#define kTopValue (1 << 24) |
|
7 |
+ |
|
8 |
+Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p) |
|
9 |
+{ |
|
10 |
+ unsigned i; |
|
11 |
+ p->Code = 0; |
|
12 |
+ p->Range = 0xFFFFFFFF; |
|
13 |
+ if (p->Stream->Read((void *)p->Stream) != 0) |
|
14 |
+ return False; |
|
15 |
+ for (i = 0; i < 4; i++) |
|
16 |
+ p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); |
|
17 |
+ return (p->Code < 0xFFFFFFFF); |
|
18 |
+} |
|
19 |
+ |
|
20 |
+static UInt32 Range_GetThreshold(void *pp, UInt32 total) |
|
21 |
+{ |
|
22 |
+ CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; |
|
23 |
+ return (p->Code) / (p->Range /= total); |
|
24 |
+} |
|
25 |
+ |
|
26 |
+static void Range_Normalize(CPpmd7z_RangeDec *p) |
|
27 |
+{ |
|
28 |
+ if (p->Range < kTopValue) |
|
29 |
+ { |
|
30 |
+ p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); |
|
31 |
+ p->Range <<= 8; |
|
32 |
+ if (p->Range < kTopValue) |
|
33 |
+ { |
|
34 |
+ p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); |
|
35 |
+ p->Range <<= 8; |
|
36 |
+ } |
|
37 |
+ } |
|
38 |
+} |
|
39 |
+ |
|
40 |
+static void Range_Decode(void *pp, UInt32 start, UInt32 size) |
|
41 |
+{ |
|
42 |
+ CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; |
|
43 |
+ p->Code -= start * p->Range; |
|
44 |
+ p->Range *= size; |
|
45 |
+ Range_Normalize(p); |
|
46 |
+} |
|
47 |
+ |
|
48 |
+static UInt32 Range_DecodeBit(void *pp, UInt32 size0) |
|
49 |
+{ |
|
50 |
+ CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; |
|
51 |
+ UInt32 newBound = (p->Range >> 14) * size0; |
|
52 |
+ UInt32 symbol; |
|
53 |
+ if (p->Code < newBound) |
|
54 |
+ { |
|
55 |
+ symbol = 0; |
|
56 |
+ p->Range = newBound; |
|
57 |
+ } |
|
58 |
+ else |
|
59 |
+ { |
|
60 |
+ symbol = 1; |
|
61 |
+ p->Code -= newBound; |
|
62 |
+ p->Range -= newBound; |
|
63 |
+ } |
|
64 |
+ Range_Normalize(p); |
|
65 |
+ return symbol; |
|
66 |
+} |
|
67 |
+ |
|
68 |
+void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p) |
|
69 |
+{ |
|
70 |
+ p->p.GetThreshold = Range_GetThreshold; |
|
71 |
+ p->p.Decode = Range_Decode; |
|
72 |
+ p->p.DecodeBit = Range_DecodeBit; |
|
73 |
+} |
|
74 |
+ |
|
75 |
+ |
|
76 |
+#define MASK(sym) ((signed char *)charMask)[sym] |
|
77 |
+ |
|
78 |
+int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc) |
|
79 |
+{ |
|
80 |
+ size_t charMask[256 / sizeof(size_t)]; |
|
81 |
+ if (p->MinContext->NumStats != 1) |
|
82 |
+ { |
|
83 |
+ CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext); |
|
84 |
+ unsigned i; |
|
85 |
+ UInt32 count, hiCnt; |
|
86 |
+ if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq)) |
|
87 |
+ { |
|
88 |
+ Byte symbol; |
|
89 |
+ rc->Decode(rc, 0, s->Freq); |
|
90 |
+ p->FoundState = s; |
|
91 |
+ symbol = s->Symbol; |
|
92 |
+ Ppmd7_Update1_0(p); |
|
93 |
+ return symbol; |
|
94 |
+ } |
|
95 |
+ p->PrevSuccess = 0; |
|
96 |
+ i = p->MinContext->NumStats - 1; |
|
97 |
+ do |
|
98 |
+ { |
|
99 |
+ if ((hiCnt += (++s)->Freq) > count) |
|
100 |
+ { |
|
101 |
+ Byte symbol; |
|
102 |
+ rc->Decode(rc, hiCnt - s->Freq, s->Freq); |
|
103 |
+ p->FoundState = s; |
|
104 |
+ symbol = s->Symbol; |
|
105 |
+ Ppmd7_Update1(p); |
|
106 |
+ return symbol; |
|
107 |
+ } |
|
108 |
+ } |
|
109 |
+ while (--i); |
|
110 |
+ if (count >= p->MinContext->SummFreq) |
|
111 |
+ return -2; |
|
112 |
+ p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]; |
|
113 |
+ rc->Decode(rc, hiCnt, p->MinContext->SummFreq - hiCnt); |
|
114 |
+ PPMD_SetAllBitsIn256Bytes(charMask); |
|
115 |
+ MASK(s->Symbol) = 0; |
|
116 |
+ i = p->MinContext->NumStats - 1; |
|
117 |
+ do { MASK((--s)->Symbol) = 0; } while (--i); |
|
118 |
+ } |
|
119 |
+ else |
|
120 |
+ { |
|
121 |
+ UInt16 *prob = Ppmd7_GetBinSumm(p); |
|
122 |
+ if (rc->DecodeBit(rc, *prob) == 0) |
|
123 |
+ { |
|
124 |
+ Byte symbol; |
|
125 |
+ *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob); |
|
126 |
+ symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol; |
|
127 |
+ Ppmd7_UpdateBin(p); |
|
128 |
+ return symbol; |
|
129 |
+ } |
|
130 |
+ *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob); |
|
131 |
+ p->InitEsc = PPMD7_kExpEscape[*prob >> 10]; |
|
132 |
+ PPMD_SetAllBitsIn256Bytes(charMask); |
|
133 |
+ MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0; |
|
134 |
+ p->PrevSuccess = 0; |
|
135 |
+ } |
|
136 |
+ for (;;) |
|
137 |
+ { |
|
138 |
+ CPpmd_State *ps[256], *s; |
|
139 |
+ UInt32 freqSum, count, hiCnt; |
|
140 |
+ CPpmd_See *see; |
|
141 |
+ unsigned i, num, numMasked = p->MinContext->NumStats; |
|
142 |
+ do |
|
143 |
+ { |
|
144 |
+ p->OrderFall++; |
|
145 |
+ if (!p->MinContext->Suffix) |
|
146 |
+ return -1; |
|
147 |
+ p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix); |
|
148 |
+ } |
|
149 |
+ while (p->MinContext->NumStats == numMasked); |
|
150 |
+ hiCnt = 0; |
|
151 |
+ s = Ppmd7_GetStats(p, p->MinContext); |
|
152 |
+ i = 0; |
|
153 |
+ num = p->MinContext->NumStats - numMasked; |
|
154 |
+ do |
|
155 |
+ { |
|
156 |
+ int k = (int)(MASK(s->Symbol)); |
|
157 |
+ hiCnt += (s->Freq & k); |
|
158 |
+ ps[i] = s++; |
|
159 |
+ i -= k; |
|
160 |
+ } |
|
161 |
+ while (i != num); |
|
162 |
+ |
|
163 |
+ see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum); |
|
164 |
+ freqSum += hiCnt; |
|
165 |
+ count = rc->GetThreshold(rc, freqSum); |
|
166 |
+ |
|
167 |
+ if (count < hiCnt) |
|
168 |
+ { |
|
169 |
+ Byte symbol; |
|
170 |
+ CPpmd_State **pps = ps; |
|
171 |
+ for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++); |
|
172 |
+ s = *pps; |
|
173 |
+ rc->Decode(rc, hiCnt - s->Freq, s->Freq); |
|
174 |
+ Ppmd_See_Update(see); |
|
175 |
+ p->FoundState = s; |
|
176 |
+ symbol = s->Symbol; |
|
177 |
+ Ppmd7_Update2(p); |
|
178 |
+ return symbol; |
|
179 |
+ } |
|
180 |
+ if (count >= freqSum) |
|
181 |
+ return -2; |
|
182 |
+ rc->Decode(rc, hiCnt, freqSum - hiCnt); |
|
183 |
+ see->Summ = (UInt16)(see->Summ + freqSum); |
|
184 |
+ do { MASK(ps[--i]->Symbol) = 0; } while (i != 0); |
|
185 |
+ } |
|
186 |
+} |
... | ... |
@@ -1,213 +1,255 @@ |
1 |
-/* Types.h -- Basic types |
|
2 |
-2008-11-23 : Igor Pavlov : Public domain */ |
|
3 |
- |
|
4 |
-#ifndef __7Z_TYPES_H |
|
5 |
-#define __7Z_TYPES_H |
|
6 |
- |
|
7 |
-#include <stddef.h> |
|
8 |
- |
|
9 |
-#ifdef _WIN32 |
|
10 |
-#include <windows.h> |
|
11 |
-#endif |
|
12 |
- |
|
13 |
-/* aCaB -- lame workaround for "Byte" refef */ |
|
14 |
-#include <zconf.h> |
|
15 |
- |
|
16 |
-#define SZ_OK 0 |
|
17 |
- |
|
18 |
-#define SZ_ERROR_DATA 1 |
|
19 |
-#define SZ_ERROR_MEM 2 |
|
20 |
-#define SZ_ERROR_CRC 3 |
|
21 |
-#define SZ_ERROR_UNSUPPORTED 4 |
|
22 |
-#define SZ_ERROR_PARAM 5 |
|
23 |
-#define SZ_ERROR_INPUT_EOF 6 |
|
24 |
-#define SZ_ERROR_OUTPUT_EOF 7 |
|
25 |
-#define SZ_ERROR_READ 8 |
|
26 |
-#define SZ_ERROR_WRITE 9 |
|
27 |
-#define SZ_ERROR_PROGRESS 10 |
|
28 |
-#define SZ_ERROR_FAIL 11 |
|
29 |
-#define SZ_ERROR_THREAD 12 |
|
30 |
- |
|
31 |
-#define SZ_ERROR_ARCHIVE 16 |
|
32 |
-#define SZ_ERROR_NO_ARCHIVE 17 |
|
33 |
- |
|
34 |
-typedef int SRes; |
|
35 |
- |
|
36 |
-#ifdef _WIN32 |
|
37 |
-typedef DWORD WRes; |
|
38 |
-#else |
|
39 |
-typedef int WRes; |
|
40 |
-#endif |
|
41 |
- |
|
42 |
-#ifndef RINOK |
|
43 |
-#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } |
|
44 |
-#endif |
|
45 |
- |
|
46 |
-/* aCaB -- use Byte defined in zconf.h |
|
47 |
-typedef unsigned char Byte; |
|
48 |
-*/ |
|
49 |
-typedef short Int16; |
|
50 |
-typedef unsigned short UInt16; |
|
51 |
- |
|
52 |
-#ifdef _LZMA_UINT32_IS_ULONG |
|
53 |
-typedef long Int32; |
|
54 |
-typedef unsigned long UInt32; |
|
55 |
-#else |
|
56 |
-typedef int Int32; |
|
57 |
-typedef unsigned int UInt32; |
|
58 |
-#endif |
|
59 |
- |
|
60 |
-#ifdef _SZ_NO_INT_64 |
|
61 |
- |
|
62 |
-/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. |
|
63 |
- NOTES: Some code will work incorrectly in that case! */ |
|
64 |
- |
|
65 |
-typedef long Int64; |
|
66 |
-typedef unsigned long UInt64; |
|
67 |
- |
|
68 |
-#else |
|
69 |
- |
|
70 |
-#if defined(_MSC_VER) || defined(__BORLANDC__) |
|
71 |
-typedef __int64 Int64; |
|
72 |
-typedef unsigned __int64 UInt64; |
|
73 |
-#else |
|
74 |
-typedef long long int Int64; |
|
75 |
-typedef unsigned long long int UInt64; |
|
76 |
-#endif |
|
77 |
- |
|
78 |
-#endif |
|
79 |
- |
|
80 |
-#ifdef _LZMA_NO_SYSTEM_SIZE_T |
|
81 |
-typedef UInt32 SizeT; |
|
82 |
-#else |
|
83 |
-typedef size_t SizeT; |
|
84 |
-#endif |
|
85 |
- |
|
86 |
-typedef int Bool; |
|
87 |
-#define True 1 |
|
88 |
-#define False 0 |
|
89 |
- |
|
90 |
- |
|
91 |
-#ifdef _MSC_VER |
|
92 |
- |
|
93 |
-#if _MSC_VER >= 1300 |
|
94 |
-#define MY_NO_INLINE __declspec(noinline) |
|
95 |
-#else |
|
96 |
-#define MY_NO_INLINE |
|
97 |
-#endif |
|
98 |
- |
|
99 |
-#define MY_CDECL __cdecl |
|
100 |
-#define MY_STD_CALL __stdcall |
|
101 |
-#define MY_FAST_CALL MY_NO_INLINE __fastcall |
|
102 |
- |
|
103 |
-#else |
|
104 |
- |
|
105 |
-#define MY_CDECL |
|
106 |
-#define MY_STD_CALL |
|
107 |
-#define MY_FAST_CALL |
|
108 |
- |
|
109 |
-#endif |
|
110 |
- |
|
111 |
- |
|
112 |
-/* The following interfaces use first parameter as pointer to structure */ |
|
113 |
- |
|
114 |
-typedef struct |
|
115 |
-{ |
|
116 |
- SRes (*Read)(void *p, void *buf, size_t *size); |
|
117 |
- /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. |
|
118 |
- (output(*size) < input(*size)) is allowed */ |
|
119 |
-} ISeqInStream; |
|
120 |
- |
|
121 |
-/* it can return SZ_ERROR_INPUT_EOF */ |
|
122 |
-SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); |
|
123 |
-SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); |
|
124 |
-SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); |
|
125 |
- |
|
126 |
-typedef struct |
|
127 |
-{ |
|
128 |
- size_t (*Write)(void *p, const void *buf, size_t size); |
|
129 |
- /* Returns: result - the number of actually written bytes. |
|
130 |
- (result < size) means error */ |
|
131 |
-} ISeqOutStream; |
|
132 |
- |
|
133 |
-typedef enum |
|
134 |
-{ |
|
135 |
- SZ_SEEK_SET = 0, |
|
136 |
- SZ_SEEK_CUR = 1, |
|
137 |
- SZ_SEEK_END = 2 |
|
138 |
-} ESzSeek; |
|
139 |
- |
|
140 |
-typedef struct |
|
141 |
-{ |
|
142 |
- SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ |
|
143 |
- SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); |
|
144 |
-} ISeekInStream; |
|
145 |
- |
|
146 |
-typedef struct |
|
147 |
-{ |
|
148 |
- SRes (*Look)(void *p, void **buf, size_t *size); |
|
149 |
- /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. |
|
150 |
- (output(*size) > input(*size)) is not allowed |
|
151 |
- (output(*size) < input(*size)) is allowed */ |
|
152 |
- SRes (*Skip)(void *p, size_t offset); |
|
153 |
- /* offset must be <= output(*size) of Look */ |
|
154 |
- |
|
155 |
- SRes (*Read)(void *p, void *buf, size_t *size); |
|
156 |
- /* reads directly (without buffer). It's same as ISeqInStream::Read */ |
|
157 |
- SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); |
|
158 |
-} ILookInStream; |
|
159 |
- |
|
160 |
-SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); |
|
161 |
-SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); |
|
162 |
- |
|
163 |
-/* reads via ILookInStream::Read */ |
|
164 |
-SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); |
|
165 |
-SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); |
|
166 |
- |
|
167 |
-#define LookToRead_BUF_SIZE (1 << 14) |
|
168 |
- |
|
169 |
-typedef struct |
|
170 |
-{ |
|
171 |
- ILookInStream s; |
|
172 |
- ISeekInStream *realStream; |
|
173 |
- size_t pos; |
|
174 |
- size_t size; |
|
175 |
- Byte buf[LookToRead_BUF_SIZE]; |
|
176 |
-} CLookToRead; |
|
177 |
- |
|
178 |
-void LookToRead_CreateVTable(CLookToRead *p, int lookahead); |
|
179 |
-void LookToRead_Init(CLookToRead *p); |
|
180 |
- |
|
181 |
-typedef struct |
|
182 |
-{ |
|
183 |
- ISeqInStream s; |
|
184 |
- ILookInStream *realStream; |
|
185 |
-} CSecToLook; |
|
186 |
- |
|
187 |
-void SecToLook_CreateVTable(CSecToLook *p); |
|
188 |
- |
|
189 |
-typedef struct |
|
190 |
-{ |
|
191 |
- ISeqInStream s; |
|
192 |
- ILookInStream *realStream; |
|
193 |
-} CSecToRead; |
|
194 |
- |
|
195 |
-void SecToRead_CreateVTable(CSecToRead *p); |
|
196 |
- |
|
197 |
-typedef struct |
|
198 |
-{ |
|
199 |
- SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); |
|
200 |
- /* Returns: result. (result != SZ_OK) means break. |
|
201 |
- Value (UInt64)(Int64)-1 for size means unknown value. */ |
|
202 |
-} ICompressProgress; |
|
203 |
- |
|
204 |
-typedef struct |
|
205 |
-{ |
|
206 |
- void *(*Alloc)(void *p, size_t size); |
|
207 |
- void (*Free)(void *p, void *address); /* address can be 0 */ |
|
208 |
-} ISzAlloc; |
|
209 |
- |
|
210 |
-#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) |
|
211 |
-#define IAlloc_Free(p, a) (p)->Free((p), a) |
|
212 |
- |
|
213 |
-#endif |
|
1 |
+/* Types.h -- Basic types |
|
2 |
+2010-10-09 : Igor Pavlov : Public domain */ |
|
3 |
+ |
|
4 |
+#ifndef __7Z_TYPES_H |
|
5 |
+#define __7Z_TYPES_H |
|
6 |
+ |
|
7 |
+#include <stddef.h> |
|
8 |
+ |
|
9 |
+#ifdef _WIN32 |
|
10 |
+#include <windows.h> |
|
11 |
+#endif |
|
12 |
+ |
|
13 |
+#ifndef EXTERN_C_BEGIN |
|
14 |
+#ifdef __cplusplus |
|
15 |
+#define EXTERN_C_BEGIN extern "C" { |
|
16 |
+#define EXTERN_C_END } |
|
17 |
+#else |
|
18 |
+#define EXTERN_C_BEGIN |
|
19 |
+#define EXTERN_C_END |
|
20 |
+#endif |
|
21 |
+#endif |
|
22 |
+ |
|
23 |
+EXTERN_C_BEGIN |
|
24 |
+#include "fmap.h" |
|
25 |
+#define SZ_OK 0 |
|
26 |
+ |
|
27 |
+#define SZ_ERROR_DATA 1 |
|
28 |
+#define SZ_ERROR_MEM 2 |
|
29 |
+#define SZ_ERROR_CRC 3 |
|
30 |
+#define SZ_ERROR_UNSUPPORTED 4 |
|
31 |
+#define SZ_ERROR_PARAM 5 |
|
32 |
+#define SZ_ERROR_INPUT_EOF 6 |
|
33 |
+#define SZ_ERROR_OUTPUT_EOF 7 |
|
34 |
+#define SZ_ERROR_READ 8 |
|
35 |
+#define SZ_ERROR_WRITE 9 |
|
36 |
+#define SZ_ERROR_PROGRESS 10 |
|
37 |
+#define SZ_ERROR_FAIL 11 |
|
38 |
+#define SZ_ERROR_THREAD 12 |
|
39 |
+ |
|
40 |
+#define SZ_ERROR_ARCHIVE 16 |
|
41 |
+#define SZ_ERROR_NO_ARCHIVE 17 |
|
42 |
+ |
|
43 |
+typedef int SRes; |
|
44 |
+ |
|
45 |
+#ifdef _WIN32 |
|
46 |
+typedef DWORD WRes; |
|
47 |
+#else |
|
48 |
+typedef int WRes; |
|
49 |
+#endif |
|
50 |
+ |
|
51 |
+#ifndef RINOK |
|
52 |
+#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } |
|
53 |
+#endif |
|
54 |
+ |
|
55 |
+typedef unsigned char Byte; |
|
56 |
+typedef short Int16; |
|
57 |
+typedef unsigned short UInt16; |
|
58 |
+ |
|
59 |
+#ifdef _LZMA_UINT32_IS_ULONG |
|
60 |
+typedef long Int32; |
|
61 |
+typedef unsigned long UInt32; |
|
62 |
+#else |
|
63 |
+typedef int Int32; |
|
64 |
+typedef unsigned int UInt32; |
|
65 |
+#endif |
|
66 |
+ |
|
67 |
+#ifdef _SZ_NO_INT_64 |
|
68 |
+ |
|
69 |
+/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. |
|
70 |
+ NOTES: Some code will work incorrectly in that case! */ |
|
71 |
+ |
|
72 |
+typedef long Int64; |
|
73 |
+typedef unsigned long UInt64; |
|
74 |
+ |
|
75 |
+#else |
|
76 |
+ |
|
77 |
+#if defined(_MSC_VER) || defined(__BORLANDC__) |
|
78 |
+typedef __int64 Int64; |
|
79 |
+typedef unsigned __int64 UInt64; |
|
80 |
+#define UINT64_CONST(n) n |
|
81 |
+#else |
|
82 |
+typedef long long int Int64; |
|
83 |
+typedef unsigned long long int UInt64; |
|
84 |
+#define UINT64_CONST(n) n ## ULL |
|
85 |
+#endif |
|
86 |
+ |
|
87 |
+#endif |
|
88 |
+ |
|
89 |
+#ifdef _LZMA_NO_SYSTEM_SIZE_T |
|
90 |
+typedef UInt32 SizeT; |
|
91 |
+#else |
|
92 |
+typedef size_t SizeT; |
|
93 |
+#endif |
|
94 |
+ |
|
95 |
+typedef int Bool; |
|
96 |
+#define True 1 |
|
97 |
+#define False 0 |
|
98 |
+ |
|
99 |
+ |
|
100 |
+#ifdef _WIN32 |
|
101 |
+#define MY_STD_CALL __stdcall |
|
102 |
+#else |
|
103 |
+#define MY_STD_CALL |
|
104 |
+#endif |
|
105 |
+ |
|
106 |
+#ifdef _MSC_VER |
|
107 |
+ |
|
108 |
+#if _MSC_VER >= 1300 |
|
109 |
+#define MY_NO_INLINE __declspec(noinline) |
|
110 |
+#else |
|
111 |
+#define MY_NO_INLINE |
|
112 |
+#endif |
|
113 |
+ |
|
114 |
+#define MY_CDECL __cdecl |
|
115 |
+#define MY_FAST_CALL __fastcall |
|
116 |
+ |
|
117 |
+#else |
|
118 |
+ |
|
119 |
+#define MY_CDECL |
|
120 |
+#define MY_FAST_CALL |
|
121 |
+ |
|
122 |
+#endif |
|
123 |
+ |
|
124 |
+ |
|
125 |
+/* The following interfaces use first parameter as pointer to structure */ |
|
126 |
+ |
|
127 |
+typedef struct |
|
128 |
+{ |
|
129 |
+ Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */ |
|
130 |
+} IByteIn; |
|
131 |
+ |
|
132 |
+typedef struct |
|
133 |
+{ |
|
134 |
+ void (*Write)(void *p, Byte b); |
|
135 |
+} IByteOut; |
|
136 |
+ |
|
137 |
+typedef struct |
|
138 |
+{ |
|
139 |
+ SRes (*Read)(void *p, void *buf, size_t *size); |
|
140 |
+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. |
|
141 |
+ (output(*size) < input(*size)) is allowed */ |
|
142 |
+} ISeqInStream; |
|
143 |
+ |
|
144 |
+/* it can return SZ_ERROR_INPUT_EOF */ |
|
145 |
+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); |
|
146 |
+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); |
|
147 |
+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); |
|
148 |
+ |
|
149 |
+typedef struct |
|
150 |
+{ |
|
151 |
+ size_t (*Write)(void *p, const void *buf, size_t size); |
|
152 |
+ /* Returns: result - the number of actually written bytes. |
|
153 |
+ (result < size) means error */ |
|
154 |
+} ISeqOutStream; |
|
155 |
+ |
|
156 |
+typedef enum |
|
157 |
+{ |
|
158 |
+ SZ_SEEK_SET = 0, |
|
159 |
+ SZ_SEEK_CUR = 1, |
|
160 |
+ SZ_SEEK_END = 2 |
|
161 |
+} ESzSeek; |
|
162 |
+ |
|
163 |
+typedef struct |
|
164 |
+{ |
|
165 |
+ SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ |
|
166 |
+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); |
|
167 |
+ off_t curpos; |
|
168 |
+} ISeekInStream; |
|
169 |
+ |
|
170 |
+typedef struct |
|
171 |
+{ |
|
172 |
+ SRes (*Look)(void *p, const void **buf, size_t *size); |
|
173 |
+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. |
|
174 |
+ (output(*size) > input(*size)) is not allowed |
|
175 |
+ (output(*size) < input(*size)) is allowed */ |
|
176 |
+ SRes (*Skip)(void *p, size_t offset); |
|
177 |
+ /* offset must be <= output(*size) of Look */ |
|
178 |
+ |
|
179 |
+ SRes (*Read)(void *p, void *buf, size_t *size); |
|
180 |
+ /* reads directly (without buffer). It's same as ISeqInStream::Read */ |
|
181 |
+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); |
|
182 |
+} ILookInStream; |
|
183 |
+ |
|
184 |
+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); |
|
185 |
+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); |
|
186 |
+ |
|
187 |
+/* reads via ILookInStream::Read */ |
|
188 |
+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); |
|
189 |
+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); |
|
190 |
+ |
|
191 |
+#define LookToRead_BUF_SIZE (1 << 14) |
|
192 |
+ |
|
193 |
+typedef struct |
|
194 |
+{ |
|
195 |
+ ILookInStream s; |
|
196 |
+ ISeekInStream *realStream; |
|
197 |
+ size_t pos; |
|
198 |
+ size_t size; |
|
199 |
+ Byte buf[LookToRead_BUF_SIZE]; |
|
200 |
+} CLookToRead; |
|
201 |
+ |
|
202 |
+void LookToRead_CreateVTable(CLookToRead *p, int lookahead); |
|
203 |
+void LookToRead_Init(CLookToRead *p); |
|
204 |
+ |
|
205 |
+typedef struct |
|
206 |
+{ |
|
207 |
+ ISeqInStream s; |
|
208 |
+ ILookInStream *realStream; |
|
209 |
+} CSecToLook; |
|
210 |
+ |
|
211 |
+void SecToLook_CreateVTable(CSecToLook *p); |
|
212 |
+ |
|
213 |
+typedef struct |
|
214 |
+{ |
|
215 |
+ ISeqInStream s; |
|
216 |
+ ILookInStream *realStream; |
|
217 |
+} CSecToRead; |
|
218 |
+ |
|
219 |
+void SecToRead_CreateVTable(CSecToRead *p); |
|
220 |
+ |
|
221 |
+typedef struct |
|
222 |
+{ |
|
223 |
+ SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); |
|
224 |
+ /* Returns: result. (result != SZ_OK) means break. |
|
225 |
+ Value (UInt64)(Int64)-1 for size means unknown value. */ |
|
226 |
+} ICompressProgress; |
|
227 |
+ |
|
228 |
+typedef struct |
|
229 |
+{ |
|
230 |
+ void *(*Alloc)(void *p, size_t size); |
|
231 |
+ void (*Free)(void *p, void *address); /* address can be 0 */ |
|
232 |
+} ISzAlloc; |
|
233 |
+ |
|
234 |
+#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) |
|
235 |
+#define IAlloc_Free(p, a) (p)->Free((p), a) |
|
236 |
+ |
|
237 |
+#ifdef _WIN32 |
|
238 |
+ |
|
239 |
+#define CHAR_PATH_SEPARATOR '\\' |
|
240 |
+#define WCHAR_PATH_SEPARATOR L'\\' |
|
241 |
+#define STRING_PATH_SEPARATOR "\\" |
|
242 |
+#define WSTRING_PATH_SEPARATOR L"\\" |
|
243 |
+ |
|
244 |
+#else |
|
245 |
+ |
|
246 |
+#define CHAR_PATH_SEPARATOR '/' |
|
247 |
+#define WCHAR_PATH_SEPARATOR L'/' |
|
248 |
+#define STRING_PATH_SEPARATOR "/" |
|
249 |
+#define WSTRING_PATH_SEPARATOR L"/" |
|
250 |
+ |
|
251 |
+#endif |
|
252 |
+ |
|
253 |
+EXTERN_C_END |
|
254 |
+ |
|
255 |
+#endif |
214 | 256 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,295 @@ |
0 |
+diff -wu lzma_orig//7zCrc.c 7z/7zCrc.c |
|
1 |
+--- lzma_orig//7zCrc.c 2011-06-18 01:48:31.343602685 +0200 |
|
2 |
+@@ -4,24 +4,12 @@ |
|
3 |
+ #include "7zCrc.h" |
|
4 |
+ #include "CpuArch.h" |
|
5 |
+ |
|
6 |
+-#define kCrcPoly 0xEDB88320 |
|
7 |
++const UInt32 g_CrcTable[256] = { 0x0, 0x77073096, 0xee0e612c, 0x990951ba, 0x76dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0xedb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x9b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x1db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x6b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0xf00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x86d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x3b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x4db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0xd6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0xa00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x26d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x5005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0xcb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0xbdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; |
|
8 |
+ |
|
9 |
+-#ifdef MY_CPU_LE |
|
10 |
+-#define CRC_NUM_TABLES 8 |
|
11 |
+-#else |
|
12 |
+-#define CRC_NUM_TABLES 1 |
|
13 |
+-#endif |
|
14 |
+ |
|
15 |
+-typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table); |
|
16 |
++#define CRC_UPDATE_BYTE_2(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) |
|
17 |
+ |
|
18 |
+-static CRC_FUNC g_CrcUpdate; |
|
19 |
+-UInt32 g_CrcTable[256 * CRC_NUM_TABLES]; |
|
20 |
+- |
|
21 |
+-#if CRC_NUM_TABLES == 1 |
|
22 |
+- |
|
23 |
+-#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) |
|
24 |
+- |
|
25 |
+-static UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table) |
|
26 |
++UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) |
|
27 |
+ { |
|
28 |
+ const Byte *p = (const Byte *)data; |
|
29 |
+ for (; size > 0; size--, p++) |
|
30 |
+@@ -29,46 +17,7 @@ |
|
31 |
+ return v; |
|
32 |
+ } |
|
33 |
+ |
|
34 |
+-#else |
|
35 |
+- |
|
36 |
+-UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); |
|
37 |
+-UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table); |
|
38 |
+- |
|
39 |
+-#endif |
|
40 |
+- |
|
41 |
+-UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) |
|
42 |
+-{ |
|
43 |
+- return g_CrcUpdate(v, data, size, g_CrcTable); |
|
44 |
+-} |
|
45 |
+- |
|
46 |
+ UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size) |
|
47 |
+ { |
|
48 |
+- return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL; |
|
49 |
+-} |
|
50 |
+- |
|
51 |
+-void MY_FAST_CALL CrcGenerateTable() |
|
52 |
+-{ |
|
53 |
+- UInt32 i; |
|
54 |
+- for (i = 0; i < 256; i++) |
|
55 |
+- { |
|
56 |
+- UInt32 r = i; |
|
57 |
+- unsigned j; |
|
58 |
+- for (j = 0; j < 8; j++) |
|
59 |
+- r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); |
|
60 |
+- g_CrcTable[i] = r; |
|
61 |
+- } |
|
62 |
+- #if CRC_NUM_TABLES == 1 |
|
63 |
+- g_CrcUpdate = CrcUpdateT1; |
|
64 |
+- #else |
|
65 |
+- for (; i < 256 * CRC_NUM_TABLES; i++) |
|
66 |
+- { |
|
67 |
+- UInt32 r = g_CrcTable[i - 256]; |
|
68 |
+- g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8); |
|
69 |
+- } |
|
70 |
+- g_CrcUpdate = CrcUpdateT4; |
|
71 |
+- #ifdef MY_CPU_X86_OR_AMD64 |
|
72 |
+- if (!CPU_Is_InOrder()) |
|
73 |
+- g_CrcUpdate = CrcUpdateT8; |
|
74 |
+- #endif |
|
75 |
+- #endif |
|
76 |
++ return CrcUpdate(CRC_INIT_VAL, data, size) ^ CRC_INIT_VAL; |
|
77 |
+ } |
|
78 |
+diff -wu lzma_orig//7zCrc.h 7z/7zCrc.h |
|
79 |
+--- lzma_orig//7zCrc.h 2011-06-18 01:48:31.343602685 +0200 |
|
80 |
+@@ -8,14 +8,7 @@ |
|
81 |
+ |
|
82 |
+ EXTERN_C_BEGIN |
|
83 |
+ |
|
84 |
+-extern UInt32 g_CrcTable[]; |
|
85 |
+- |
|
86 |
+-/* Call CrcGenerateTable one time before other CRC functions */ |
|
87 |
+-void MY_FAST_CALL CrcGenerateTable(void); |
|
88 |
+- |
|
89 |
+ #define CRC_INIT_VAL 0xFFFFFFFF |
|
90 |
+-#define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL) |
|
91 |
+-#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) |
|
92 |
+ |
|
93 |
+ UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size); |
|
94 |
+ UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size); |
|
95 |
+diff -wu lzma_orig//7zDec.c 7z/7zDec.c |
|
96 |
+--- lzma_orig//7zDec.c 2011-06-18 01:48:31.347602680 +0200 |
|
97 |
+@@ -3,7 +3,7 @@ |
|
98 |
+ |
|
99 |
+ #include <string.h> |
|
100 |
+ |
|
101 |
+-/* #define _7ZIP_PPMD_SUPPPORT */ |
|
102 |
++#define _7ZIP_PPMD_SUPPPORT |
|
103 |
+ |
|
104 |
+ #include "7z.h" |
|
105 |
+ |
|
106 |
+diff -wu lzma_orig//7zFile.h 7z/7zFile.h |
|
107 |
+--- lzma_orig//7zFile.h 2011-06-18 01:48:31.347602680 +0200 |
|
108 |
+@@ -27,6 +27,7 @@ |
|
109 |
+ #else |
|
110 |
+ FILE *file; |
|
111 |
+ #endif |
|
112 |
++ fmap_t *fmap; |
|
113 |
+ } CSzFile; |
|
114 |
+ |
|
115 |
+ void File_Construct(CSzFile *p); |
|
116 |
+diff -wu lzma_orig//CpuArch.h 7z/CpuArch.h |
|
117 |
+--- lzma_orig//CpuArch.h 2011-06-18 01:48:31.363602662 +0200 |
|
118 |
+@@ -5,6 +5,7 @@ |
|
119 |
+ #define __CPU_ARCH_H |
|
120 |
+ |
|
121 |
+ #include "Types.h" |
|
122 |
++#include "others.h" |
|
123 |
+ |
|
124 |
+ EXTERN_C_BEGIN |
|
125 |
+ |
|
126 |
+@@ -16,68 +17,8 @@ |
|
127 |
+ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform. |
|
128 |
+ */ |
|
129 |
+ |
|
130 |
+-#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) |
|
131 |
+-#define MY_CPU_AMD64 |
|
132 |
+-#endif |
|
133 |
+- |
|
134 |
+-#if defined(MY_CPU_AMD64) || defined(_M_IA64) |
|
135 |
+-#define MY_CPU_64BIT |
|
136 |
+-#endif |
|
137 |
+- |
|
138 |
+-#if defined(_M_IX86) || defined(__i386__) |
|
139 |
+-#define MY_CPU_X86 |
|
140 |
+-#endif |
|
141 |
+- |
|
142 |
+-#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64) |
|
143 |
+-#define MY_CPU_X86_OR_AMD64 |
|
144 |
+-#endif |
|
145 |
+- |
|
146 |
+-#if defined(MY_CPU_X86) || defined(_M_ARM) |
|
147 |
+-#define MY_CPU_32BIT |
|
148 |
+-#endif |
|
149 |
+- |
|
150 |
+-#if defined(_WIN32) && defined(_M_ARM) |
|
151 |
+-#define MY_CPU_ARM_LE |
|
152 |
+-#endif |
|
153 |
+- |
|
154 |
+-#if defined(_WIN32) && defined(_M_IA64) |
|
155 |
+-#define MY_CPU_IA64_LE |
|
156 |
+-#endif |
|
157 |
+- |
|
158 |
+-#if defined(MY_CPU_X86_OR_AMD64) |
|
159 |
+-#define MY_CPU_LE_UNALIGN |
|
160 |
+-#endif |
|
161 |
+- |
|
162 |
+-#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__) |
|
163 |
+-#define MY_CPU_LE |
|
164 |
+-#endif |
|
165 |
+- |
|
166 |
+-#if defined(__BIG_ENDIAN__) |
|
167 |
+-#define MY_CPU_BE |
|
168 |
+-#endif |
|
169 |
+- |
|
170 |
+-#if defined(MY_CPU_LE) && defined(MY_CPU_BE) |
|
171 |
+-Stop_Compiling_Bad_Endian |
|
172 |
+-#endif |
|
173 |
+- |
|
174 |
+-#ifdef MY_CPU_LE_UNALIGN |
|
175 |
+- |
|
176 |
+-#define GetUi16(p) (*(const UInt16 *)(p)) |
|
177 |
+-#define GetUi32(p) (*(const UInt32 *)(p)) |
|
178 |
+-#define GetUi64(p) (*(const UInt64 *)(p)) |
|
179 |
+-#define SetUi16(p, d) *(UInt16 *)(p) = (d); |
|
180 |
+-#define SetUi32(p, d) *(UInt32 *)(p) = (d); |
|
181 |
+-#define SetUi64(p, d) *(UInt64 *)(p) = (d); |
|
182 |
+- |
|
183 |
+-#else |
|
184 |
+- |
|
185 |
+-#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8)) |
|
186 |
+- |
|
187 |
+-#define GetUi32(p) ( \ |
|
188 |
+- ((const Byte *)(p))[0] | \ |
|
189 |
+- ((UInt32)((const Byte *)(p))[1] << 8) | \ |
|
190 |
+- ((UInt32)((const Byte *)(p))[2] << 16) | \ |
|
191 |
+- ((UInt32)((const Byte *)(p))[3] << 24)) |
|
192 |
++#define GetUi16(p) (cli_readint16(p)) |
|
193 |
++#define GetUi32(p) (cli_readint32(p)) |
|
194 |
+ |
|
195 |
+ #define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) |
|
196 |
+ |
|
197 |
+@@ -85,71 +26,12 @@ |
|
198 |
+ ((Byte *)(p))[0] = (Byte)_x_; \ |
|
199 |
+ ((Byte *)(p))[1] = (Byte)(_x_ >> 8); } |
|
200 |
+ |
|
201 |
+-#define SetUi32(p, d) { UInt32 _x_ = (d); \ |
|
202 |
+- ((Byte *)(p))[0] = (Byte)_x_; \ |
|
203 |
+- ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \ |
|
204 |
+- ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \ |
|
205 |
+- ((Byte *)(p))[3] = (Byte)(_x_ >> 24); } |
|
206 |
++#define SetUi32(p, d) (cli_writeint32(p, d)) |
|
207 |
+ |
|
208 |
+ #define SetUi64(p, d) { UInt64 _x64_ = (d); \ |
|
209 |
+ SetUi32(p, (UInt32)_x64_); \ |
|
210 |
+ SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); } |
|
211 |
+ |
|
212 |
+-#endif |
|
213 |
+- |
|
214 |
+-#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300) |
|
215 |
+- |
|
216 |
+-#pragma intrinsic(_byteswap_ulong) |
|
217 |
+-#pragma intrinsic(_byteswap_uint64) |
|
218 |
+-#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p)) |
|
219 |
+-#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p)) |
|
220 |
+- |
|
221 |
+-#else |
|
222 |
+- |
|
223 |
+-#define GetBe32(p) ( \ |
|
224 |
+- ((UInt32)((const Byte *)(p))[0] << 24) | \ |
|
225 |
+- ((UInt32)((const Byte *)(p))[1] << 16) | \ |
|
226 |
+- ((UInt32)((const Byte *)(p))[2] << 8) | \ |
|
227 |
+- ((const Byte *)(p))[3] ) |
|
228 |
+- |
|
229 |
+-#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) |
|
230 |
+- |
|
231 |
+-#endif |
|
232 |
+- |
|
233 |
+-#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1]) |
|
234 |
+- |
|
235 |
+- |
|
236 |
+-#ifdef MY_CPU_X86_OR_AMD64 |
|
237 |
+- |
|
238 |
+-typedef struct |
|
239 |
+-{ |
|
240 |
+- UInt32 maxFunc; |
|
241 |
+- UInt32 vendor[3]; |
|
242 |
+- UInt32 ver; |
|
243 |
+- UInt32 b; |
|
244 |
+- UInt32 c; |
|
245 |
+- UInt32 d; |
|
246 |
+-} Cx86cpuid; |
|
247 |
+- |
|
248 |
+-enum |
|
249 |
+-{ |
|
250 |
+- CPU_FIRM_INTEL, |
|
251 |
+- CPU_FIRM_AMD, |
|
252 |
+- CPU_FIRM_VIA |
|
253 |
+-}; |
|
254 |
+- |
|
255 |
+-Bool x86cpuid_CheckAndRead(Cx86cpuid *p); |
|
256 |
+-int x86cpuid_GetFirm(const Cx86cpuid *p); |
|
257 |
+- |
|
258 |
+-#define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F) |
|
259 |
+-#define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F) |
|
260 |
+-#define x86cpuid_GetStepping(p) ((p)->ver & 0xF) |
|
261 |
+- |
|
262 |
+-Bool CPU_Is_InOrder(); |
|
263 |
+-Bool CPU_Is_Aes_Supported(); |
|
264 |
+- |
|
265 |
+-#endif |
|
266 |
+- |
|
267 |
+ EXTERN_C_END |
|
268 |
+ |
|
269 |
+ #endif |
|
270 |
+diff -wu lzma_orig//Types.h 7z/Types.h |
|
271 |
+--- lzma_orig//Types.h 2011-06-18 01:48:31.379602643 +0200 |
|
272 |
+@@ -21,7 +21,7 @@ |
|
273 |
+ #endif |
|
274 |
+ |
|
275 |
+ EXTERN_C_BEGIN |
|
276 |
+- |
|
277 |
++#include "fmap.h" |
|
278 |
+ #define SZ_OK 0 |
|
279 |
+ |
|
280 |
+ #define SZ_ERROR_DATA 1 |
|
281 |
+@@ -164,6 +164,7 @@ |
|
282 |
+ { |
|
283 |
+ SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ |
|
284 |
+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); |
|
285 |
++ off_t curpos; |
|
286 |
+ } ISeekInStream; |
|
287 |
+ |
|
288 |
+ typedef struct |
0 | 289 |
deleted file mode 100644 |
... | ... |
@@ -1,594 +0,0 @@ |
1 |
-LZMA SDK 4.65 |
|
2 |
- |
|
3 |
-LZMA SDK provides the documentation, samples, header files, libraries, |
|
4 |
-and tools you need to develop applications that use LZMA compression. |
|
5 |
- |
|
6 |
-LZMA is default and general compression method of 7z format |
|
7 |
-in 7-Zip compression program (www.7-zip.org). LZMA provides high |
|
8 |
-compression ratio and very fast decompression. |
|
9 |
- |
|
10 |
-LZMA is an improved version of famous LZ77 compression algorithm. |
|
11 |
-It was improved in way of maximum increasing of compression ratio, |
|
12 |
-keeping high decompression speed and low memory requirements for |
|
13 |
-decompressing. |
|
14 |
- |
|
15 |
- |
|
16 |
- |
|
17 |
-LICENSE |
|
18 |
- |
|
19 |
-LZMA SDK is written and placed in the public domain by Igor Pavlov. |
|
20 |
- |
|
21 |
- |
|
22 |
-LZMA SDK Contents |
|
23 |
- |
|
24 |
-LZMA SDK includes: |
|
25 |
- |
|
26 |
- - ANSI-C/C++/C#/Java source code for LZMA compressing and decompressing |
|
27 |
- - Compiled file->file LZMA compressing/decompressing program for Windows system |
|
28 |
- |
|
29 |
- |
|
30 |
-UNIX/Linux version |
|
31 |
-To compile C++ version of file->file LZMA encoding, go to directory |
|
32 |
-C++/7zip/Compress/LZMA_Alone |
|
33 |
-and call make to recompile it: |
|
34 |
- make -f makefile.gcc clean all |
|
35 |
- |
|
36 |
-In some UNIX/Linux versions you must compile LZMA with static libraries. |
|
37 |
-To compile with static libraries, you can use |
|
38 |
-LIB = -lm -static |
|
39 |
- |
|
40 |
- |
|
41 |
-Files |
|
42 |
-lzma.txt - LZMA SDK description (this file) |
|
43 |
-7zFormat.txt - 7z Format description |
|
44 |
-7zC.txt - 7z ANSI-C Decoder description |
|
45 |
-methods.txt - Compression method IDs for .7z |
|
46 |
-lzma.exe - Compiled file->file LZMA encoder/decoder for Windows |
|
47 |
-history.txt - history of the LZMA SDK |
|
48 |
- |
|
49 |
- |
|
50 |
-Source code structure |
|
51 |
- |
|
52 |
-C/ - C files |
|
53 |
- 7zCrc*.* - CRC code |
|
54 |
- Alloc.* - Memory allocation functions |
|
55 |
- Bra*.* - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code |
|
56 |
- LzFind.* - Match finder for LZ (LZMA) encoders |
|
57 |
- LzFindMt.* - Match finder for LZ (LZMA) encoders for multithreading encoding |
|
58 |
- LzHash.h - Additional file for LZ match finder |
|
59 |
- LzmaDec.* - LZMA decoding |
|
60 |
- LzmaEnc.* - LZMA encoding |
|
61 |
- LzmaLib.* - LZMA Library for DLL calling |
|
62 |
- Types.h - Basic types for another .c files |
|
63 |
- Threads.* - The code for multithreading. |
|
64 |
- |
|
65 |
- LzmaLib - LZMA Library (.DLL for Windows) |
|
66 |
- |
|
67 |
- LzmaUtil - LZMA Utility (file->file LZMA encoder/decoder). |
|
68 |
- |
|
69 |
- Archive - files related to archiving |
|
70 |
- 7z - 7z ANSI-C Decoder |
|
71 |
- |
|
72 |
-CPP/ -- CPP files |
|
73 |
- |
|
74 |
- Common - common files for C++ projects |
|
75 |
- Windows - common files for Windows related code |
|
76 |
- |
|
77 |
- 7zip - files related to 7-Zip Project |
|
78 |
- |
|
79 |
- Common - common files for 7-Zip |
|
80 |
- |
|
81 |
- Compress - files related to compression/decompression |
|
82 |
- |
|
83 |
- Copy - Copy coder |
|
84 |
- RangeCoder - Range Coder (special code of compression/decompression) |
|
85 |
- LZMA - LZMA compression/decompression on C++ |
|
86 |
- LZMA_Alone - file->file LZMA compression/decompression |
|
87 |
- Branch - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code |
|
88 |
- |
|
89 |
- Archive - files related to archiving |
|
90 |
- |
|
91 |
- Common - common files for archive handling |
|
92 |
- 7z - 7z C++ Encoder/Decoder |
|
93 |
- |
|
94 |
- Bundles - Modules that are bundles of other modules |
|
95 |
- |
|
96 |
- Alone7z - 7zr.exe: Standalone version of 7z.exe that supports only 7z/LZMA/BCJ/BCJ2 |
|
97 |
- Format7zR - 7zr.dll: Reduced version of 7za.dll: extracting/compressing to 7z/LZMA/BCJ/BCJ2 |
|
98 |
- Format7zExtractR - 7zxr.dll: Reduced version of 7zxa.dll: extracting from 7z/LZMA/BCJ/BCJ2. |
|
99 |
- |
|
100 |
- UI - User Interface files |
|
101 |
- |
|
102 |
- Client7z - Test application for 7za.dll, 7zr.dll, 7zxr.dll |
|
103 |
- Common - Common UI files |
|
104 |
- Console - Code for console archiver |
|
105 |
- |
|
106 |
- |
|
107 |
- |
|
108 |
-CS/ - C# files |
|
109 |
- 7zip |
|
110 |
- Common - some common files for 7-Zip |
|
111 |
- Compress - files related to compression/decompression |
|
112 |
- LZ - files related to LZ (Lempel-Ziv) compression algorithm |
|
113 |
- LZMA - LZMA compression/decompression |
|
114 |
- LzmaAlone - file->file LZMA compression/decompression |
|
115 |
- RangeCoder - Range Coder (special code of compression/decompression) |
|
116 |
- |
|
117 |
-Java/ - Java files |
|
118 |
- SevenZip |
|
119 |
- Compression - files related to compression/decompression |
|
120 |
- LZ - files related to LZ (Lempel-Ziv) compression algorithm |
|
121 |
- LZMA - LZMA compression/decompression |
|
122 |
- RangeCoder - Range Coder (special code of compression/decompression) |
|
123 |
- |
|
124 |
- |
|
125 |
-C/C++ source code of LZMA SDK is part of 7-Zip project. |
|
126 |
-7-Zip source code can be downloaded from 7-Zip's SourceForge page: |
|
127 |
- |
|
128 |
- http://sourceforge.net/projects/sevenzip/ |
|
129 |
- |
|
130 |
- |
|
131 |
- |
|
132 |
-LZMA features |
|
133 |
- - Variable dictionary size (up to 1 GB) |
|
134 |
- - Estimated compressing speed: about 2 MB/s on 2 GHz CPU |
|
135 |
- - Estimated decompressing speed: |
|
136 |
- - 20-30 MB/s on 2 GHz Core 2 or AMD Athlon 64 |
|
137 |
- - 1-2 MB/s on 200 MHz ARM, MIPS, PowerPC or other simple RISC |
|
138 |
- - Small memory requirements for decompressing (16 KB + DictionarySize) |
|
139 |
- - Small code size for decompressing: 5-8 KB |
|
140 |
- |
|
141 |
-LZMA decoder uses only integer operations and can be |
|
142 |
-implemented in any modern 32-bit CPU (or on 16-bit CPU with some conditions). |
|
143 |
- |
|
144 |
-Some critical operations that affect the speed of LZMA decompression: |
|
145 |
- 1) 32*16 bit integer multiply |
|
146 |
- 2) Misspredicted branches (penalty mostly depends from pipeline length) |
|
147 |
- 3) 32-bit shift and arithmetic operations |
|
148 |
- |
|
149 |
-The speed of LZMA decompressing mostly depends from CPU speed. |
|
150 |
-Memory speed has no big meaning. But if your CPU has small data cache, |
|
151 |
-overall weight of memory speed will slightly increase. |
|
152 |
- |
|
153 |
- |
|
154 |
-How To Use |
|
155 |
- |
|
156 |
-Using LZMA encoder/decoder executable |
|
157 |
- |
|
158 |
-Usage: LZMA <e|d> inputFile outputFile [<switches>...] |
|
159 |
- |
|
160 |
- e: encode file |
|
161 |
- |
|
162 |
- d: decode file |
|
163 |
- |
|
164 |
- b: Benchmark. There are two tests: compressing and decompressing |
|
165 |
- with LZMA method. Benchmark shows rating in MIPS (million |
|
166 |
- instructions per second). Rating value is calculated from |
|
167 |
- measured speed and it is normalized with Intel's Core 2 results. |
|
168 |
- Also Benchmark checks possible hardware errors (RAM |
|
169 |
- errors in most cases). Benchmark uses these settings: |
|
170 |
- (-a1, -d21, -fb32, -mfbt4). You can change only -d parameter. |
|
171 |
- Also you can change the number of iterations. Example for 30 iterations: |
|
172 |
- LZMA b 30 |
|
173 |
- Default number of iterations is 10. |
|
174 |
- |
|
175 |
-<Switches> |
|
176 |
- |
|
177 |
- |
|
178 |
- -a{N}: set compression mode 0 = fast, 1 = normal |
|
179 |
- default: 1 (normal) |
|
180 |
- |
|
181 |
- d{N}: Sets Dictionary size - [0, 30], default: 23 (8MB) |
|
182 |
- The maximum value for dictionary size is 1 GB = 2^30 bytes. |
|
183 |
- Dictionary size is calculated as DictionarySize = 2^N bytes. |
|
184 |
- For decompressing file compressed by LZMA method with dictionary |
|
185 |
- size D = 2^N you need about D bytes of memory (RAM). |
|
186 |
- |
|
187 |
- -fb{N}: set number of fast bytes - [5, 273], default: 128 |
|
188 |
- Usually big number gives a little bit better compression ratio |
|
189 |
- and slower compression process. |
|
190 |
- |
|
191 |
- -lc{N}: set number of literal context bits - [0, 8], default: 3 |
|
192 |
- Sometimes lc=4 gives gain for big files. |
|
193 |
- |
|
194 |
- -lp{N}: set number of literal pos bits - [0, 4], default: 0 |
|
195 |
- lp switch is intended for periodical data when period is |
|
196 |
- equal 2^N. For example, for 32-bit (4 bytes) |
|
197 |
- periodical data you can use lp=2. Often it's better to set lc0, |
|
198 |
- if you change lp switch. |
|
199 |
- |
|
200 |
- -pb{N}: set number of pos bits - [0, 4], default: 2 |
|
201 |
- pb switch is intended for periodical data |
|
202 |
- when period is equal 2^N. |
|
203 |
- |
|
204 |
- -mf{MF_ID}: set Match Finder. Default: bt4. |
|
205 |
- Algorithms from hc* group doesn't provide good compression |
|
206 |
- ratio, but they often works pretty fast in combination with |
|
207 |
- fast mode (-a0). |
|
208 |
- |
|
209 |
- Memory requirements depend from dictionary size |
|
210 |
- (parameter "d" in table below). |
|
211 |
- |
|
212 |
- MF_ID Memory Description |
|
213 |
- |
|
214 |
- bt2 d * 9.5 + 4MB Binary Tree with 2 bytes hashing. |
|
215 |
- bt3 d * 11.5 + 4MB Binary Tree with 3 bytes hashing. |
|
216 |
- bt4 d * 11.5 + 4MB Binary Tree with 4 bytes hashing. |
|
217 |
- hc4 d * 7.5 + 4MB Hash Chain with 4 bytes hashing. |
|
218 |
- |
|
219 |
- -eos: write End Of Stream marker. By default LZMA doesn't write |
|
220 |
- eos marker, since LZMA decoder knows uncompressed size |
|
221 |
- stored in .lzma file header. |
|
222 |
- |
|
223 |
- -si: Read data from stdin (it will write End Of Stream marker). |
|
224 |
- -so: Write data to stdout |
|
225 |
- |
|
226 |
- |
|
227 |
-Examples: |
|
228 |
- |
|
229 |
-1) LZMA e file.bin file.lzma -d16 -lc0 |
|
230 |
- |
|
231 |
-compresses file.bin to file.lzma with 64 KB dictionary (2^16=64K) |
|
232 |
-and 0 literal context bits. -lc0 allows to reduce memory requirements |
|
233 |
-for decompression. |
|
234 |
- |
|
235 |
- |
|
236 |
-2) LZMA e file.bin file.lzma -lc0 -lp2 |
|
237 |
- |
|
238 |
-compresses file.bin to file.lzma with settings suitable |
|
239 |
-for 32-bit periodical data (for example, ARM or MIPS code). |
|
240 |
- |
|
241 |
-3) LZMA d file.lzma file.bin |
|
242 |
- |
|
243 |
-decompresses file.lzma to file.bin. |
|
244 |
- |
|
245 |
- |
|
246 |
-Compression ratio hints |
|
247 |
- |
|
248 |
-Recommendations |
|
249 |
- |
|
250 |
-To increase the compression ratio for LZMA compressing it's desirable |
|
251 |
-to have aligned data (if it's possible) and also it's desirable to locate |
|
252 |
-data in such order, where code is grouped in one place and data is |
|
253 |
-grouped in other place (it's better than such mixing: code, data, code, |
|
254 |
-data, ...). |
|
255 |
- |
|
256 |
- |
|
257 |
-Filters |
|
258 |
-You can increase the compression ratio for some data types, using |
|
259 |
-special filters before compressing. For example, it's possible to |
|
260 |
-increase the compression ratio on 5-10% for code for those CPU ISAs: |
|
261 |
-x86, IA-64, ARM, ARM-Thumb, PowerPC, SPARC. |
|
262 |
- |
|
263 |
-You can find C source code of such filters in C/Bra*.* files |
|
264 |
- |
|
265 |
-You can check the compression ratio gain of these filters with such |
|
266 |
-7-Zip commands (example for ARM code): |
|
267 |
-No filter: |
|
268 |
- 7z a a1.7z a.bin -m0=lzma |
|
269 |
- |
|
270 |
-With filter for little-endian ARM code: |
|
271 |
- 7z a a2.7z a.bin -m0=arm -m1=lzma |
|
272 |
- |
|
273 |
-It works in such manner: |
|
274 |
-Compressing = Filter_encoding + LZMA_encoding |
|
275 |
-Decompressing = LZMA_decoding + Filter_decoding |
|
276 |
- |
|
277 |
-Compressing and decompressing speed of such filters is very high, |
|
278 |
-so it will not increase decompressing time too much. |
|
279 |
-Moreover, it reduces decompression time for LZMA_decoding, |
|
280 |
-since compression ratio with filtering is higher. |
|
281 |
- |
|
282 |
-These filters convert CALL (calling procedure) instructions |
|
283 |
-from relative offsets to absolute addresses, so such data becomes more |
|
284 |
-compressible. |
|
285 |
- |
|
286 |
-For some ISAs (for example, for MIPS) it's impossible to get gain from such filter. |
|
287 |
- |
|
288 |
- |
|
289 |
-LZMA compressed file format |
|
290 |
-Offset Size Description |
|
291 |
- 0 1 Special LZMA properties (lc,lp, pb in encoded form) |
|
292 |
- 1 4 Dictionary size (little endian) |
|
293 |
- 5 8 Uncompressed size (little endian). -1 means unknown size |
|
294 |
- 13 Compressed data |
|
295 |
- |
|
296 |
- |
|
297 |
-ANSI-C LZMA Decoder |
|
298 |
-~~~~~~~~~~~~~~~~~~~ |
|
299 |
- |
|
300 |
-Please note that interfaces for ANSI-C code were changed in LZMA SDK 4.58. |
|
301 |
-If you want to use old interfaces you can download previous version of LZMA SDK |
|
302 |
-from sourceforge.net site. |
|
303 |
- |
|
304 |
-To use ANSI-C LZMA Decoder you need the following files: |
|
305 |
-1) LzmaDec.h + LzmaDec.c + Types.h |
|
306 |
-LzmaUtil/LzmaUtil.c is example application that uses these files. |
|
307 |
- |
|
308 |
- |
|
309 |
-Memory requirements for LZMA decoding |
|
310 |
- |
|
311 |
-Stack usage of LZMA decoding function for local variables is not |
|
312 |
-larger than 200-400 bytes. |
|
313 |
- |
|
314 |
-LZMA Decoder uses dictionary buffer and internal state structure. |
|
315 |
-Internal state structure consumes |
|
316 |
- state_size = (4 + (1.5 << (lc + lp))) KB |
|
317 |
-by default (lc=3, lp=0), state_size = 16 KB. |
|
318 |
- |
|
319 |
- |
|
320 |
-How To decompress data |
|
321 |
- |
|
322 |
-LZMA Decoder (ANSI-C version) now supports 2 interfaces: |
|
323 |
-1) Single-call Decompressing |
|
324 |
-2) Multi-call State Decompressing (zlib-like interface) |
|
325 |
- |
|
326 |
-You must use external allocator: |
|
327 |
-Example: |
|
328 |
-void *SzAlloc(void *p, size_t size) { p = p; return malloc(size); } |
|
329 |
-void SzFree(void *p, void *address) { p = p; free(address); } |
|
330 |
-ISzAlloc alloc = { SzAlloc, SzFree }; |
|
331 |
- |
|
332 |
-You can use p = p; operator to disable compiler warnings. |
|
333 |
- |
|
334 |
- |
|
335 |
-Single-call Decompressing |
|
336 |
-When to use: RAM->RAM decompressing |
|
337 |
-Compile files: LzmaDec.h + LzmaDec.c + Types.h |
|
338 |
-Compile defines: no defines |
|
339 |
-Memory Requirements: |
|
340 |
- - Input buffer: compressed size |
|
341 |
- - Output buffer: uncompressed size |
|
342 |
- - LZMA Internal Structures: state_size (16 KB for default settings) |
|
343 |
- |
|
344 |
-Interface: |
|
345 |
- int LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, |
|
346 |
- const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, |
|
347 |
- ELzmaStatus *status, ISzAlloc *alloc); |
|
348 |
- In: |
|
349 |
- dest - output data |
|
350 |
- destLen - output data size |
|
351 |
- src - input data |
|
352 |
- srcLen - input data size |
|
353 |
- propData - LZMA properties (5 bytes) |
|
354 |
- propSize - size of propData buffer (5 bytes) |
|
355 |
- finishMode - It has meaning only if the decoding reaches output limit (*destLen). |
|
356 |
- LZMA_FINISH_ANY - Decode just destLen bytes. |
|
357 |
- LZMA_FINISH_END - Stream must be finished after (*destLen). |
|
358 |
- You can use LZMA_FINISH_END, when you know that |
|
359 |
- current output buffer covers last bytes of stream. |
|
360 |
- alloc - Memory allocator. |
|
361 |
- |
|
362 |
- Out: |
|
363 |
- destLen - processed output size |
|
364 |
- srcLen - processed input size |
|
365 |
- |
|
366 |
- Output: |
|
367 |
- SZ_OK |
|
368 |
- status: |
|
369 |
- LZMA_STATUS_FINISHED_WITH_MARK |
|
370 |
- LZMA_STATUS_NOT_FINISHED |
|
371 |
- LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK |
|
372 |
- SZ_ERROR_DATA - Data error |
|
373 |
- SZ_ERROR_MEM - Memory allocation error |
|
374 |
- SZ_ERROR_UNSUPPORTED - Unsupported properties |
|
375 |
- SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). |
|
376 |
- |
|
377 |
- If LZMA decoder sees end_marker before reaching output limit, it returns OK result, |
|
378 |
- and output value of destLen will be less than output buffer size limit. |
|
379 |
- |
|
380 |
- You can use multiple checks to test data integrity after full decompression: |
|
381 |
- 1) Check Result and "status" variable. |
|
382 |
- 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. |
|
383 |
- 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. |
|
384 |
- You must use correct finish mode in that case. */ |
|
385 |
- |
|
386 |
- |
|
387 |
-Multi-call State Decompressing (zlib-like interface) |
|
388 |
- |
|
389 |
-When to use: file->file decompressing |
|
390 |
-Compile files: LzmaDec.h + LzmaDec.c + Types.h |
|
391 |
- |
|
392 |
-Memory Requirements: |
|
393 |
- - Buffer for input stream: any size (for example, 16 KB) |
|
394 |
- - Buffer for output stream: any size (for example, 16 KB) |
|
395 |
- - LZMA Internal Structures: state_size (16 KB for default settings) |
|
396 |
- - LZMA dictionary (dictionary size is encoded in LZMA properties header) |
|
397 |
- |
|
398 |
-1) read LZMA properties (5 bytes) and uncompressed size (8 bytes, little-endian) to header: |
|
399 |
- unsigned char header[LZMA_PROPS_SIZE + 8]; |
|
400 |
- ReadFile(inFile, header, sizeof(header) |
|
401 |
- |
|
402 |
-2) Allocate CLzmaDec structures (state + dictionary) using LZMA properties |
|
403 |
- |
|
404 |
- CLzmaDec state; |
|
405 |
- LzmaDec_Constr(&state); |
|
406 |
- res = LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc); |
|
407 |
- if (res != SZ_OK) |
|
408 |
- return res; |
|
409 |
- |
|
410 |
-3) Init LzmaDec structure before any new LZMA stream. And call LzmaDec_DecodeToBuf in loop |
|
411 |
- |
|
412 |
- LzmaDec_Init(&state); |
|
413 |
- for (;;) |
|
414 |
- { |
|
415 |
- ... |
|
416 |
- int res = LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, |
|
417 |
- const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode); |
|
418 |
- ... |
|
419 |
- } |
|
420 |
- |
|
421 |
- |
|
422 |
-4) Free all allocated structures |
|
423 |
- LzmaDec_Free(&state, &g_Alloc); |
|
424 |
- |
|
425 |
-For full code example, look at C/LzmaUtil/LzmaUtil.c code. |
|
426 |
- |
|
427 |
- |
|
428 |
-How To compress data |
|
429 |
- |
|
430 |
-Compile files: LzmaEnc.h + LzmaEnc.c + Types.h + |
|
431 |
-LzFind.c + LzFind.h + LzFindMt.c + LzFindMt.h + LzHash.h |
|
432 |
- |
|
433 |
-Memory Requirements: |
|
434 |
- - (dictSize * 11.5 + 6 MB) + state_size |
|
435 |
- |
|
436 |
-Lzma Encoder can use two memory allocators: |
|
437 |
-1) alloc - for small arrays. |
|
438 |
-2) allocBig - for big arrays. |
|
439 |
- |
|
440 |
-For example, you can use Large RAM Pages (2 MB) in allocBig allocator for |
|
441 |
-better compression speed. Note that Windows has bad implementation for |
|
442 |
-Large RAM Pages. |
|
443 |
-It's OK to use same allocator for alloc and allocBig. |
|
444 |
- |
|
445 |
- |
|
446 |
-Single-call Compression with callbacks |
|
447 |
- |
|
448 |
-Check C/LzmaUtil/LzmaUtil.c as example, |
|
449 |
- |
|
450 |
-When to use: file->file decompressing |
|
451 |
- |
|
452 |
-1) you must implement callback structures for interfaces: |
|
453 |
-ISeqInStream |
|
454 |
-ISeqOutStream |
|
455 |
-ICompressProgress |
|
456 |
-ISzAlloc |
|
457 |
- |
|
458 |
-static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } |
|
459 |
-static void SzFree(void *p, void *address) { p = p; MyFree(address); } |
|
460 |
-static ISzAlloc g_Alloc = { SzAlloc, SzFree }; |
|
461 |
- |
|
462 |
- CFileSeqInStream inStream; |
|
463 |
- CFileSeqOutStream outStream; |
|
464 |
- |
|
465 |
- inStream.funcTable.Read = MyRead; |
|
466 |
- inStream.file = inFile; |
|
467 |
- outStream.funcTable.Write = MyWrite; |
|
468 |
- outStream.file = outFile; |
|
469 |
- |
|
470 |
- |
|
471 |
-2) Create CLzmaEncHandle object; |
|
472 |
- |
|
473 |
- CLzmaEncHandle enc; |
|
474 |
- |
|
475 |
- enc = LzmaEnc_Create(&g_Alloc); |
|
476 |
- if (enc == 0) |
|
477 |
- return SZ_ERROR_MEM; |
|
478 |
- |
|
479 |
- |
|
480 |
-3) initialize CLzmaEncProps properties; |
|
481 |
- |
|
482 |
- LzmaEncProps_Init(&props); |
|
483 |
- |
|
484 |
- Then you can change some properties in that structure. |
|
485 |
- |
|
486 |
-4) Send LZMA properties to LZMA Encoder |
|
487 |
- |
|
488 |
- res = LzmaEnc_SetProps(enc, &props); |
|
489 |
- |
|
490 |
-5) Write encoded properties to header |
|
491 |
- |
|
492 |
- Byte header[LZMA_PROPS_SIZE + 8]; |
|
493 |
- size_t headerSize = LZMA_PROPS_SIZE; |
|
494 |
- UInt64 fileSize; |
|
495 |
- int i; |
|
496 |
- |
|
497 |
- res = LzmaEnc_WriteProperties(enc, header, &headerSize); |
|
498 |
- fileSize = MyGetFileLength(inFile); |
|
499 |
- for (i = 0; i < 8; i++) |
|
500 |
- header[headerSize++] = (Byte)(fileSize >> (8 * i)); |
|
501 |
- MyWriteFileAndCheck(outFile, header, headerSize) |
|
502 |
- |
|
503 |
-6) Call encoding function: |
|
504 |
- res = LzmaEnc_Encode(enc, &outStream.funcTable, &inStream.funcTable, |
|
505 |
- NULL, &g_Alloc, &g_Alloc); |
|
506 |
- |
|
507 |
-7) Destroy LZMA Encoder Object |
|
508 |
- LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc); |
|
509 |
- |
|
510 |
- |
|
511 |
-If callback function return some error code, LzmaEnc_Encode also returns that code. |
|
512 |
- |
|
513 |
- |
|
514 |
-Single-call RAM->RAM Compression |
|
515 |
- |
|
516 |
-Single-call RAM->RAM Compression is similar to Compression with callbacks, |
|
517 |
-but you provide pointers to buffers instead of pointers to stream callbacks: |
|
518 |
- |
|
519 |
-HRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, |
|
520 |
- CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, |
|
521 |
- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); |
|
522 |
- |
|
523 |
-Return code: |
|
524 |
- SZ_OK - OK |
|
525 |
- SZ_ERROR_MEM - Memory allocation error |
|
526 |
- SZ_ERROR_PARAM - Incorrect paramater |
|
527 |
- SZ_ERROR_OUTPUT_EOF - output buffer overflow |
|
528 |
- SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) |
|
529 |
- |
|
530 |
- |
|
531 |
- |
|
532 |
-LZMA Defines |
|
533 |
- |
|
534 |
-_LZMA_SIZE_OPT - Enable some optimizations in LZMA Decoder to get smaller executable code. |
|
535 |
- |
|
536 |
-_LZMA_PROB32 - It can increase the speed on some 32-bit CPUs, but memory usage for |
|
537 |
- some structures will be doubled in that case. |
|
538 |
- |
|
539 |
-_LZMA_UINT32_IS_ULONG - Define it if int is 16-bit on your compiler and long is 32-bit. |
|
540 |
- |
|
541 |
-_LZMA_NO_SYSTEM_SIZE_T - Define it if you don't want to use size_t type. |
|
542 |
- |
|
543 |
- |
|
544 |
-C++ LZMA Encoder/Decoder |
|
545 |
-~~~~~~~~~~~~~~~~~~~~~~~~ |
|
546 |
-C++ LZMA code use COM-like interfaces. So if you want to use it, |
|
547 |
-you can study basics of COM/OLE. |
|
548 |
-C++ LZMA code is just wrapper over ANSI-C code. |
|
549 |
- |
|
550 |
- |
|
551 |
-C++ Notes |
|
552 |
-~~~~~~~~~~~~~~~~~~~~~~~~ |
|
553 |
-If you use some C++ code folders in 7-Zip (for example, C++ code for .7z handling), |
|
554 |
-you must check that you correctly work with "new" operator. |
|
555 |
-7-Zip can be compiled with MSVC 6.0 that doesn't throw "exception" from "new" operator. |
|
556 |
-So 7-Zip uses "CPP\Common\NewHandler.cpp" that redefines "new" operator: |
|
557 |
-operator new(size_t size) |
|
558 |
-{ |
|
559 |
- void *p = ::malloc(size); |
|
560 |
- if (p == 0) |
|
561 |
- throw CNewException(); |
|
562 |
- return p; |
|
563 |
-} |
|
564 |
-If you use MSCV that throws exception for "new" operator, you can compile without |
|
565 |
-"NewHandler.cpp". So standard exception will be used. Actually some code of |
|
566 |
-7-Zip catches any exception in internal code and converts it to HRESULT code. |
|
567 |
-So you don't need to catch CNewException, if you call COM interfaces of 7-Zip. |
|
568 |
- |
|
569 |
- |
|
570 |
-http://www.7-zip.org |
|
571 |
-http://www.7-zip.org/sdk.html |
|
572 |
-http://www.7-zip.org/support.html |
573 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,179 @@ |
0 |
+/* |
|
1 |
+ * Copyright (C) 2011 Sourcefire, Inc. |
|
2 |
+ * |
|
3 |
+ * Authors: aCaB |
|
4 |
+ * |
|
5 |
+ * This program is free software; you can redistribute it and/or modify |
|
6 |
+ * it under the terms of the GNU General Public License version 2 as |
|
7 |
+ * published by the Free Software Foundation. |
|
8 |
+ * |
|
9 |
+ * This program is distributed in the hope that it will be useful, |
|
10 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
+ * GNU General Public License for more details. |
|
13 |
+ * |
|
14 |
+ * You should have received a copy of the GNU General Public License |
|
15 |
+ * along with this program; if not, write to the Free Software |
|
16 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
17 |
+ * MA 02110-1301, USA. |
|
18 |
+ */ |
|
19 |
+ |
|
20 |
+ |
|
21 |
+#include "7z_iface.h" |
|
22 |
+#include "lzma_iface.h" |
|
23 |
+#include "scanners.h" |
|
24 |
+#include "others.h" |
|
25 |
+#include "fmap.h" |
|
26 |
+ |
|
27 |
+#include "7z/7z.h" |
|
28 |
+#include "7z/7zAlloc.h" |
|
29 |
+#include "7z/7zFile.h" |
|
30 |
+ |
|
31 |
+ |
|
32 |
+static ISzAlloc allocImp = { __lzma_wrap_alloc, __lzma_wrap_free}, allocTempImp = { __lzma_wrap_alloc, __lzma_wrap_free}; |
|
33 |
+ |
|
34 |
+static SRes FileInStream_fmap_Read(void *pp, void *buf, size_t *size) { |
|
35 |
+ CFileInStream *p = (CFileInStream *)pp; |
|
36 |
+ int read_sz; |
|
37 |
+ |
|
38 |
+ if (*size == 0) |
|
39 |
+ return 0; |
|
40 |
+ |
|
41 |
+ read_sz = fmap_readn(p->file.fmap, buf, p->s.curpos, *size); |
|
42 |
+ if(read_sz < 0) |
|
43 |
+ return SZ_ERROR_READ; |
|
44 |
+ |
|
45 |
+ p->s.curpos += read_sz; |
|
46 |
+ |
|
47 |
+ *size = read_sz; |
|
48 |
+ return SZ_OK; |
|
49 |
+} |
|
50 |
+ |
|
51 |
+static SRes FileInStream_fmap_Seek(void *pp, Int64 *pos, ESzSeek origin) { |
|
52 |
+ CFileInStream *p = (CFileInStream *)pp; |
|
53 |
+ |
|
54 |
+ switch (origin) { |
|
55 |
+ case SZ_SEEK_SET: |
|
56 |
+ p->s.curpos = *pos; |
|
57 |
+ break; |
|
58 |
+ case SZ_SEEK_CUR: |
|
59 |
+ p->s.curpos += *pos; |
|
60 |
+ *pos = p->s.curpos; |
|
61 |
+ break; |
|
62 |
+ case SZ_SEEK_END: |
|
63 |
+ p->s.curpos = p->file.fmap->len + *pos; |
|
64 |
+ *pos = p->s.curpos; |
|
65 |
+ break; |
|
66 |
+ default: |
|
67 |
+ return 1; |
|
68 |
+ } |
|
69 |
+ return 0; |
|
70 |
+} |
|
71 |
+ |
|
72 |
+#define UTFBUFSZ 256 |
|
73 |
+int cli_7unz (cli_ctx *ctx) { |
|
74 |
+ CFileInStream archiveStream; |
|
75 |
+ CLookToRead lookStream; |
|
76 |
+ CSzArEx db; |
|
77 |
+ SRes res; |
|
78 |
+ UInt16 utf16buf[UTFBUFSZ], *utf16name = utf16buf; |
|
79 |
+ int namelen = UTFBUFSZ, found = CL_CLEAN; |
|
80 |
+ |
|
81 |
+ /* Replacement for |
|
82 |
+ FileInStream_CreateVTable(&archiveStream); */ |
|
83 |
+ archiveStream.s.Read = FileInStream_fmap_Read; |
|
84 |
+ archiveStream.s.Seek = FileInStream_fmap_Seek; |
|
85 |
+ archiveStream.s.curpos = 0; |
|
86 |
+ archiveStream.file.fmap = *ctx->fmap; |
|
87 |
+ |
|
88 |
+ LookToRead_CreateVTable(&lookStream, False); |
|
89 |
+ |
|
90 |
+ lookStream.realStream = &archiveStream.s; |
|
91 |
+ LookToRead_Init(&lookStream); |
|
92 |
+ |
|
93 |
+ SzArEx_Init(&db); |
|
94 |
+ res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp); |
|
95 |
+ if(res == SZ_OK) { |
|
96 |
+ UInt32 i, blockIndex = 0xFFFFFFFF; |
|
97 |
+ Byte *outBuffer = 0; |
|
98 |
+ size_t outBufferSize = 0; |
|
99 |
+ |
|
100 |
+ for (i = 0; i < db.db.NumFiles; i++) { |
|
101 |
+ size_t offset = 0; |
|
102 |
+ size_t outSizeProcessed = 0; |
|
103 |
+ const CSzFileItem *f = db.db.Files + i; |
|
104 |
+ char *name; |
|
105 |
+ size_t j; |
|
106 |
+ int newnamelen, fd; |
|
107 |
+ |
|
108 |
+ if((found = cli_checklimits("7unz", ctx, 0, 0, 0))) |
|
109 |
+ break; |
|
110 |
+ |
|
111 |
+ if (f->IsDir) |
|
112 |
+ continue; |
|
113 |
+ |
|
114 |
+ if(cli_checklimits("7unz", ctx, f->Size, 0, 0)) |
|
115 |
+ continue; |
|
116 |
+ |
|
117 |
+ newnamelen = SzArEx_GetFileNameUtf16(&db, i, NULL); |
|
118 |
+ if (newnamelen > namelen) { |
|
119 |
+ if(namelen > UTFBUFSZ) |
|
120 |
+ free(utf16name); |
|
121 |
+ utf16name = cli_malloc(newnamelen*2); |
|
122 |
+ if(!utf16name) { |
|
123 |
+ found = CL_EMEM; |
|
124 |
+ break; |
|
125 |
+ } |
|
126 |
+ namelen = newnamelen; |
|
127 |
+ } |
|
128 |
+ SzArEx_GetFileNameUtf16(&db, i, utf16name); |
|
129 |
+ |
|
130 |
+ name = (char *)utf16name; |
|
131 |
+ for(j=0; j<newnamelen; j++) /* FIXME */ |
|
132 |
+ name[j] = utf16name[j]; |
|
133 |
+ cli_dbgmsg("cli_7unz: extracting %s\n", name); |
|
134 |
+ if(cli_matchmeta(ctx, name, 0, f->Size, 0, i, f->CrcDefined ? f->Crc : 0, NULL)) { |
|
135 |
+ found = CL_VIRUS; |
|
136 |
+ break; |
|
137 |
+ } |
|
138 |
+ |
|
139 |
+ res = SzArEx_Extract(&db, &lookStream.s, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocTempImp); |
|
140 |
+ if (res != SZ_OK) |
|
141 |
+ break; |
|
142 |
+ else { |
|
143 |
+ if((found = cli_gentempfd(NULL, &name, &fd))) |
|
144 |
+ break; |
|
145 |
+ |
|
146 |
+ cli_dbgmsg("cli_7unz: Saving to %s\n", name); |
|
147 |
+ if(cli_writen(fd, outBuffer + offset, outSizeProcessed) != outSizeProcessed) |
|
148 |
+ found = CL_EWRITE; |
|
149 |
+ else |
|
150 |
+ found = cli_magic_scandesc(fd, ctx); |
|
151 |
+ close(fd); |
|
152 |
+ if(!ctx->engine->keeptmp && cli_unlink(name)) |
|
153 |
+ found = CL_EUNLINK; |
|
154 |
+ |
|
155 |
+ free(name); |
|
156 |
+ if(found != CL_CLEAN) |
|
157 |
+ break; |
|
158 |
+ } |
|
159 |
+ } |
|
160 |
+ IAlloc_Free(&allocImp, outBuffer); |
|
161 |
+ } |
|
162 |
+ SzArEx_Free(&db, &allocImp); |
|
163 |
+ if(namelen > UTFBUFSZ) |
|
164 |
+ free(utf16name); |
|
165 |
+ |
|
166 |
+ if (res == SZ_OK) |
|
167 |
+ cli_dbgmsg("cli_7unz: completed successfully\n"); |
|
168 |
+ else if (res == SZ_ERROR_UNSUPPORTED) |
|
169 |
+ cli_dbgmsg("cli_7unz: unsupported\n"); |
|
170 |
+ else if (res == SZ_ERROR_MEM) |
|
171 |
+ cli_dbgmsg("cli_7unz: oom\n"); |
|
172 |
+ else if (res == SZ_ERROR_CRC) |
|
173 |
+ cli_dbgmsg("cli_7unz: crc mismatch\n"); |
|
174 |
+ else |
|
175 |
+ cli_dbgmsg("cli_7unz: error %d\n", res); |
|
176 |
+ |
|
177 |
+ return found; |
|
178 |
+} |
0 | 179 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,32 @@ |
0 |
+/* |
|
1 |
+ * Copyright (C) 2011 Sourcefire, Inc. |
|
2 |
+ * |
|
3 |
+ * Authors: aCaB |
|
4 |
+ * |
|
5 |
+ * This program is free software; you can redistribute it and/or modify |
|
6 |
+ * it under the terms of the GNU General Public License version 2 as |
|
7 |
+ * published by the Free Software Foundation. |
|
8 |
+ * |
|
9 |
+ * This program is distributed in the hope that it will be useful, |
|
10 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
+ * GNU General Public License for more details. |
|
13 |
+ * |
|
14 |
+ * You should have received a copy of the GNU General Public License |
|
15 |
+ * along with this program; if not, write to the Free Software |
|
16 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
17 |
+ * MA 02110-1301, USA. |
|
18 |
+ */ |
|
19 |
+ |
|
20 |
+#ifndef __7Z_IFACE_H |
|
21 |
+#define __7Z_IFACE_H |
|
22 |
+ |
|
23 |
+#if HAVE_CONFIG_H |
|
24 |
+#include "clamav-config.h" |
|
25 |
+#endif |
|
26 |
+ |
|
27 |
+#include "others.h" |
|
28 |
+ |
|
29 |
+int cli_7unz (cli_ctx *); |
|
30 |
+ |
|
31 |
+#endif |
... | ... |
@@ -281,36 +281,39 @@ libclamav_la_SOURCES = \ |
281 | 281 |
hashtab.h \ |
282 | 282 |
dconf.c \ |
283 | 283 |
dconf.h \ |
284 |
- 7z/LzmaDec.c \ |
|
285 |
- 7z/LzmaDec.h \ |
|
286 |
- 7z/Types.h \ |
|
287 | 284 |
lzma_iface.c \ |
288 | 285 |
lzma_iface.h \ |
289 |
- 7z.c \ |
|
290 |
- 7z.h \ |
|
286 |
+ 7z_iface.c \ |
|
287 |
+ 7z_iface.h \ |
|
288 |
+ 7z/7z.h \ |
|
289 |
+ 7z/7zAlloc.c \ |
|
290 |
+ 7z/7zAlloc.h \ |
|
291 |
+ 7z/7zBuf.c \ |
|
292 |
+ 7z/7zBuf.h \ |
|
293 |
+ 7z/7zBuf2.c \ |
|
294 |
+ 7z/7zCrc.c \ |
|
295 |
+ 7z/7zCrc.h \ |
|
296 |
+ 7z/7zDec.c \ |
|
291 | 297 |
7z/7zFile.c \ |
292 | 298 |
7z/7zFile.h \ |
299 |
+ 7z/7zIn.c \ |
|
293 | 300 |
7z/7zStream.c \ |
294 |
- 7z/CpuArch.h \ |
|
295 |
- 7z/7zCrc.c \ |
|
296 |
- 7z/7zCrc.h \ |
|
297 |
- 7z/7zBuf.c \ |
|
298 |
- 7z/7zBuf.h \ |
|
301 |
+ 7z/7zVersion.h \ |
|
299 | 302 |
7z/Bcj2.c \ |
300 | 303 |
7z/Bcj2.h \ |
301 | 304 |
7z/Bra.c \ |
302 | 305 |
7z/Bra.h \ |
303 | 306 |
7z/Bra86.c \ |
304 |
- 7z/Archive/7z/7zIn.c \ |
|
305 |
- 7z/Archive/7z/7zIn.h \ |
|
306 |
- 7z/Archive/7z/7zDecode.c \ |
|
307 |
- 7z/Archive/7z/7zDecode.h \ |
|
308 |
- 7z/Archive/7z/7zItem.c \ |
|
309 |
- 7z/Archive/7z/7zItem.h \ |
|
310 |
- 7z/Archive/7z/7zHeader.c \ |
|
311 |
- 7z/Archive/7z/7zHeader.h \ |
|
312 |
- 7z/Archive/7z/7zExtract.c \ |
|
313 |
- 7z/Archive/7z/7zExtract.h \ |
|
307 |
+ 7z/CpuArch.h \ |
|
308 |
+ 7z/Lzma2Dec.c \ |
|
309 |
+ 7z/Lzma2Dec.h \ |
|
310 |
+ 7z/LzmaDec.c \ |
|
311 |
+ 7z/LzmaDec.h \ |
|
312 |
+ 7z/Ppmd.h \ |
|
313 |
+ 7z/Ppmd7.c \ |
|
314 |
+ 7z/Ppmd7.h \ |
|
315 |
+ 7z/Ppmd7Dec.c \ |
|
316 |
+ 7z/Types.h \ |
|
314 | 317 |
explode.c \ |
315 | 318 |
explode.h \ |
316 | 319 |
textnorm.c \ |
... | ... |
@@ -139,27 +139,25 @@ am__libclamav_la_SOURCES_DIST = clamav.h matcher-ac.c matcher-ac.h \ |
139 | 139 |
regex_list.c regex_list.h regex_suffix.c regex_suffix.h \ |
140 | 140 |
mspack.c mspack.h cab.c cab.h entconv.c entconv.h entitylist.h \ |
141 | 141 |
encoding_aliases.h hashtab.c hashtab.h dconf.c dconf.h \ |
142 |
- 7z/LzmaDec.c 7z/LzmaDec.h 7z/Types.h lzma_iface.c lzma_iface.h \ |
|
143 |
- 7z.c 7z.h 7z/7zFile.c 7z/7zFile.h 7z/7zStream.c 7z/CpuArch.h \ |
|
144 |
- 7z/7zCrc.c 7z/7zCrc.h 7z/7zBuf.c 7z/7zBuf.h 7z/Bcj2.c \ |
|
145 |
- 7z/Bcj2.h 7z/Bra.c 7z/Bra.h 7z/Bra86.c 7z/Archive/7z/7zIn.c \ |
|
146 |
- 7z/Archive/7z/7zIn.h 7z/Archive/7z/7zDecode.c \ |
|
147 |
- 7z/Archive/7z/7zDecode.h 7z/Archive/7z/7zItem.c \ |
|
148 |
- 7z/Archive/7z/7zItem.h 7z/Archive/7z/7zHeader.c \ |
|
149 |
- 7z/Archive/7z/7zHeader.h 7z/Archive/7z/7zExtract.c \ |
|
150 |
- 7z/Archive/7z/7zExtract.h explode.c explode.h textnorm.c \ |
|
151 |
- textnorm.h dlp.c dlp.h jsparse/js-norm.c jsparse/js-norm.h \ |
|
152 |
- jsparse/lexglobal.h jsparse/textbuf.h uniq.c uniq.h version.c \ |
|
153 |
- version.h mpool.c mpool.h filtering.h filtering.c fmap.c \ |
|
154 |
- fmap.h perflogging.c perflogging.h default.h sha256.c sha256.h \ |
|
155 |
- sha1.c sha1.h bignum.h bytecode.c bytecode.h bytecode_vm.c \ |
|
156 |
- bytecode_priv.h clambc.h cpio.c cpio.h macho.c macho.h \ |
|
157 |
- ishield.c ishield.h type_desc.h bcfeatures.h bytecode_api.c \ |
|
158 |
- bytecode_api_decl.c bytecode_api.h bytecode_api_impl.h \ |
|
159 |
- bytecode_hooks.h cache.c cache.h bytecode_detect.c \ |
|
160 |
- bytecode_detect.h builtin_bytecodes.h events.c events.h swf.c \ |
|
161 |
- swf.h jpeg.c jpeg.h png.c png.h arc4.c arc4.h bignum.c \ |
|
162 |
- bignum_class.h |
|
142 |
+ lzma_iface.c lzma_iface.h 7z_iface.c 7z_iface.h 7z/7z.h \ |
|
143 |
+ 7z/7zAlloc.c 7z/7zAlloc.h 7z/7zBuf.c 7z/7zBuf.h 7z/7zBuf2.c \ |
|
144 |
+ 7z/7zCrc.c 7z/7zCrc.h 7z/7zDec.c 7z/7zFile.c 7z/7zFile.h \ |
|
145 |
+ 7z/7zIn.c 7z/7zStream.c 7z/7zVersion.h 7z/Bcj2.c 7z/Bcj2.h \ |
|
146 |
+ 7z/Bra.c 7z/Bra.h 7z/Bra86.c 7z/CpuArch.h 7z/Lzma2Dec.c \ |
|
147 |
+ 7z/Lzma2Dec.h 7z/LzmaDec.c 7z/LzmaDec.h 7z/Ppmd.h 7z/Ppmd7.c \ |
|
148 |
+ 7z/Ppmd7.h 7z/Ppmd7Dec.c 7z/Types.h explode.c explode.h \ |
|
149 |
+ textnorm.c textnorm.h dlp.c dlp.h jsparse/js-norm.c \ |
|
150 |
+ jsparse/js-norm.h jsparse/lexglobal.h jsparse/textbuf.h uniq.c \ |
|
151 |
+ uniq.h version.c version.h mpool.c mpool.h filtering.h \ |
|
152 |
+ filtering.c fmap.c fmap.h perflogging.c perflogging.h \ |
|
153 |
+ default.h sha256.c sha256.h sha1.c sha1.h bignum.h bytecode.c \ |
|
154 |
+ bytecode.h bytecode_vm.c bytecode_priv.h clambc.h cpio.c \ |
|
155 |
+ cpio.h macho.c macho.h ishield.c ishield.h type_desc.h \ |
|
156 |
+ bcfeatures.h bytecode_api.c bytecode_api_decl.c bytecode_api.h \ |
|
157 |
+ bytecode_api_impl.h bytecode_hooks.h cache.c cache.h \ |
|
158 |
+ bytecode_detect.c bytecode_detect.h builtin_bytecodes.h \ |
|
159 |
+ events.c events.h swf.c swf.h jpeg.c jpeg.h png.c png.h arc4.c \ |
|
160 |
+ arc4.h bignum.c bignum_class.h |
|
163 | 161 |
@LINK_TOMMATH_FALSE@am__objects_1 = libclamav_la-bignum.lo |
164 | 162 |
am_libclamav_la_OBJECTS = libclamav_la-matcher-ac.lo \ |
165 | 163 |
libclamav_la-matcher-bm.lo libclamav_la-matcher-hash.lo \ |
... | ... |
@@ -193,13 +191,14 @@ am_libclamav_la_OBJECTS = libclamav_la-matcher-ac.lo \ |
193 | 193 |
libclamav_la-regex_suffix.lo libclamav_la-mspack.lo \ |
194 | 194 |
libclamav_la-cab.lo libclamav_la-entconv.lo \ |
195 | 195 |
libclamav_la-hashtab.lo libclamav_la-dconf.lo \ |
196 |
- libclamav_la-LzmaDec.lo libclamav_la-lzma_iface.lo \ |
|
197 |
- libclamav_la-7z.lo libclamav_la-7zFile.lo \ |
|
198 |
- libclamav_la-7zStream.lo libclamav_la-7zCrc.lo \ |
|
199 |
- libclamav_la-7zBuf.lo libclamav_la-Bcj2.lo libclamav_la-Bra.lo \ |
|
200 |
- libclamav_la-Bra86.lo libclamav_la-7zIn.lo \ |
|
201 |
- libclamav_la-7zDecode.lo libclamav_la-7zItem.lo \ |
|
202 |
- libclamav_la-7zHeader.lo libclamav_la-7zExtract.lo \ |
|
196 |
+ libclamav_la-lzma_iface.lo libclamav_la-7z_iface.lo \ |
|
197 |
+ libclamav_la-7zAlloc.lo libclamav_la-7zBuf.lo \ |
|
198 |
+ libclamav_la-7zBuf2.lo libclamav_la-7zCrc.lo \ |
|
199 |
+ libclamav_la-7zDec.lo libclamav_la-7zFile.lo \ |
|
200 |
+ libclamav_la-7zIn.lo libclamav_la-7zStream.lo \ |
|
201 |
+ libclamav_la-Bcj2.lo libclamav_la-Bra.lo libclamav_la-Bra86.lo \ |
|
202 |
+ libclamav_la-Lzma2Dec.lo libclamav_la-LzmaDec.lo \ |
|
203 |
+ libclamav_la-Ppmd7.lo libclamav_la-Ppmd7Dec.lo \ |
|
203 | 204 |
libclamav_la-explode.lo libclamav_la-textnorm.lo \ |
204 | 205 |
libclamav_la-dlp.lo libclamav_la-js-norm.lo \ |
205 | 206 |
libclamav_la-uniq.lo libclamav_la-version.lo \ |
... | ... |
@@ -652,26 +651,25 @@ libclamav_la_SOURCES = clamav.h matcher-ac.c matcher-ac.h matcher-bm.c \ |
652 | 652 |
regex_list.c regex_list.h regex_suffix.c regex_suffix.h \ |
653 | 653 |
mspack.c mspack.h cab.c cab.h entconv.c entconv.h entitylist.h \ |
654 | 654 |
encoding_aliases.h hashtab.c hashtab.h dconf.c dconf.h \ |
655 |
- 7z/LzmaDec.c 7z/LzmaDec.h 7z/Types.h lzma_iface.c lzma_iface.h \ |
|
656 |
- 7z.c 7z.h 7z/7zFile.c 7z/7zFile.h 7z/7zStream.c 7z/CpuArch.h \ |
|
657 |
- 7z/7zCrc.c 7z/7zCrc.h 7z/7zBuf.c 7z/7zBuf.h 7z/Bcj2.c \ |
|
658 |
- 7z/Bcj2.h 7z/Bra.c 7z/Bra.h 7z/Bra86.c 7z/Archive/7z/7zIn.c \ |
|
659 |
- 7z/Archive/7z/7zIn.h 7z/Archive/7z/7zDecode.c \ |
|
660 |
- 7z/Archive/7z/7zDecode.h 7z/Archive/7z/7zItem.c \ |
|
661 |
- 7z/Archive/7z/7zItem.h 7z/Archive/7z/7zHeader.c \ |
|
662 |
- 7z/Archive/7z/7zHeader.h 7z/Archive/7z/7zExtract.c \ |
|
663 |
- 7z/Archive/7z/7zExtract.h explode.c explode.h textnorm.c \ |
|
664 |
- textnorm.h dlp.c dlp.h jsparse/js-norm.c jsparse/js-norm.h \ |
|
665 |
- jsparse/lexglobal.h jsparse/textbuf.h uniq.c uniq.h version.c \ |
|
666 |
- version.h mpool.c mpool.h filtering.h filtering.c fmap.c \ |
|
667 |
- fmap.h perflogging.c perflogging.h default.h sha256.c sha256.h \ |
|
668 |
- sha1.c sha1.h bignum.h bytecode.c bytecode.h bytecode_vm.c \ |
|
669 |
- bytecode_priv.h clambc.h cpio.c cpio.h macho.c macho.h \ |
|
670 |
- ishield.c ishield.h type_desc.h bcfeatures.h bytecode_api.c \ |
|
671 |
- bytecode_api_decl.c bytecode_api.h bytecode_api_impl.h \ |
|
672 |
- bytecode_hooks.h cache.c cache.h bytecode_detect.c \ |
|
673 |
- bytecode_detect.h builtin_bytecodes.h events.c events.h swf.c \ |
|
674 |
- swf.h jpeg.c jpeg.h png.c png.h arc4.c arc4.h $(am__append_7) |
|
655 |
+ lzma_iface.c lzma_iface.h 7z_iface.c 7z_iface.h 7z/7z.h \ |
|
656 |
+ 7z/7zAlloc.c 7z/7zAlloc.h 7z/7zBuf.c 7z/7zBuf.h 7z/7zBuf2.c \ |
|
657 |
+ 7z/7zCrc.c 7z/7zCrc.h 7z/7zDec.c 7z/7zFile.c 7z/7zFile.h \ |
|
658 |
+ 7z/7zIn.c 7z/7zStream.c 7z/7zVersion.h 7z/Bcj2.c 7z/Bcj2.h \ |
|
659 |
+ 7z/Bra.c 7z/Bra.h 7z/Bra86.c 7z/CpuArch.h 7z/Lzma2Dec.c \ |
|
660 |
+ 7z/Lzma2Dec.h 7z/LzmaDec.c 7z/LzmaDec.h 7z/Ppmd.h 7z/Ppmd7.c \ |
|
661 |
+ 7z/Ppmd7.h 7z/Ppmd7Dec.c 7z/Types.h explode.c explode.h \ |
|
662 |
+ textnorm.c textnorm.h dlp.c dlp.h jsparse/js-norm.c \ |
|
663 |
+ jsparse/js-norm.h jsparse/lexglobal.h jsparse/textbuf.h uniq.c \ |
|
664 |
+ uniq.h version.c version.h mpool.c mpool.h filtering.h \ |
|
665 |
+ filtering.c fmap.c fmap.h perflogging.c perflogging.h \ |
|
666 |
+ default.h sha256.c sha256.h sha1.c sha1.h bignum.h bytecode.c \ |
|
667 |
+ bytecode.h bytecode_vm.c bytecode_priv.h clambc.h cpio.c \ |
|
668 |
+ cpio.h macho.c macho.h ishield.c ishield.h type_desc.h \ |
|
669 |
+ bcfeatures.h bytecode_api.c bytecode_api_decl.c bytecode_api.h \ |
|
670 |
+ bytecode_api_impl.h bytecode_hooks.h cache.c cache.h \ |
|
671 |
+ bytecode_detect.c bytecode_detect.h builtin_bytecodes.h \ |
|
672 |
+ events.c events.h swf.c swf.h jpeg.c jpeg.h png.c png.h arc4.c \ |
|
673 |
+ arc4.h $(am__append_7) |
|
675 | 674 |
noinst_LTLIBRARIES = libclamav_internal_utils.la libclamav_internal_utils_nothreads.la libclamav_nocxx.la |
676 | 675 |
COMMON_CLEANFILES = version.h version.h.tmp *.gcda *.gcno |
677 | 676 |
@MAINTAINER_MODE_TRUE@BUILT_SOURCES = jsparse/generated/operators.h jsparse/generated/keywords.h jsparse-keywords.gperf |
... | ... |
@@ -791,20 +789,22 @@ distclean-compile: |
791 | 791 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_internal_utils_nothreads_la-regfree.Plo@am__quote@ |
792 | 792 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_internal_utils_nothreads_la-str.Plo@am__quote@ |
793 | 793 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_internal_utils_nothreads_la-strlcpy.Plo@am__quote@ |
794 |
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7z.Plo@am__quote@ |
|
794 |
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7zAlloc.Plo@am__quote@ |
|
795 | 795 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7zBuf.Plo@am__quote@ |
796 |
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7zBuf2.Plo@am__quote@ |
|
796 | 797 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7zCrc.Plo@am__quote@ |
797 |
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7zDecode.Plo@am__quote@ |
|
798 |
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7zExtract.Plo@am__quote@ |
|
798 |
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7zDec.Plo@am__quote@ |
|
799 | 799 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7zFile.Plo@am__quote@ |
800 |
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7zHeader.Plo@am__quote@ |
|
801 | 800 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7zIn.Plo@am__quote@ |
802 |
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7zItem.Plo@am__quote@ |
|
803 | 801 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7zStream.Plo@am__quote@ |
802 |
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7z_iface.Plo@am__quote@ |
|
804 | 803 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-Bcj2.Plo@am__quote@ |
805 | 804 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-Bra.Plo@am__quote@ |
806 | 805 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-Bra86.Plo@am__quote@ |
806 |
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-Lzma2Dec.Plo@am__quote@ |
|
807 | 807 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-LzmaDec.Plo@am__quote@ |
808 |
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-Ppmd7.Plo@am__quote@ |
|
809 |
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-Ppmd7Dec.Plo@am__quote@ |
|
808 | 810 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-arc4.Plo@am__quote@ |
809 | 811 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-aspack.Plo@am__quote@ |
810 | 812 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-autoit.Plo@am__quote@ |
... | ... |
@@ -1443,14 +1443,6 @@ libclamav_la-dconf.lo: dconf.c |
1443 | 1443 |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
1444 | 1444 |
@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-dconf.lo `test -f 'dconf.c' || echo '$(srcdir)/'`dconf.c |
1445 | 1445 |
|
1446 |
-libclamav_la-LzmaDec.lo: 7z/LzmaDec.c |
|
1447 |
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-LzmaDec.lo -MD -MP -MF $(DEPDIR)/libclamav_la-LzmaDec.Tpo -c -o libclamav_la-LzmaDec.lo `test -f '7z/LzmaDec.c' || echo '$(srcdir)/'`7z/LzmaDec.c |
|
1448 |
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-LzmaDec.Tpo $(DEPDIR)/libclamav_la-LzmaDec.Plo |
|
1449 |
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ |
|
1450 |
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='7z/LzmaDec.c' object='libclamav_la-LzmaDec.lo' libtool=yes @AMDEPBACKSLASH@ |
|
1451 |
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
|
1452 |
-@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-LzmaDec.lo `test -f '7z/LzmaDec.c' || echo '$(srcdir)/'`7z/LzmaDec.c |
|
1453 |
- |
|
1454 | 1446 |
libclamav_la-lzma_iface.lo: lzma_iface.c |
1455 | 1447 |
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-lzma_iface.lo -MD -MP -MF $(DEPDIR)/libclamav_la-lzma_iface.Tpo -c -o libclamav_la-lzma_iface.lo `test -f 'lzma_iface.c' || echo '$(srcdir)/'`lzma_iface.c |
1456 | 1448 |
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-lzma_iface.Tpo $(DEPDIR)/libclamav_la-lzma_iface.Plo |
... | ... |
@@ -1459,29 +1451,37 @@ libclamav_la-lzma_iface.lo: lzma_iface.c |
1459 | 1459 |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
1460 | 1460 |
@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-lzma_iface.lo `test -f 'lzma_iface.c' || echo '$(srcdir)/'`lzma_iface.c |
1461 | 1461 |
|
1462 |
-libclamav_la-7z.lo: 7z.c |
|
1463 |
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7z.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7z.Tpo -c -o libclamav_la-7z.lo `test -f '7z.c' || echo '$(srcdir)/'`7z.c |
|
1464 |
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-7z.Tpo $(DEPDIR)/libclamav_la-7z.Plo |
|
1462 |
+libclamav_la-7z_iface.lo: 7z_iface.c |
|
1463 |
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7z_iface.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7z_iface.Tpo -c -o libclamav_la-7z_iface.lo `test -f '7z_iface.c' || echo '$(srcdir)/'`7z_iface.c |
|
1464 |
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-7z_iface.Tpo $(DEPDIR)/libclamav_la-7z_iface.Plo |
|
1465 | 1465 |
@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ |
1466 |
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='7z.c' object='libclamav_la-7z.lo' libtool=yes @AMDEPBACKSLASH@ |
|
1466 |
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='7z_iface.c' object='libclamav_la-7z_iface.lo' libtool=yes @AMDEPBACKSLASH@ |
|
1467 | 1467 |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
1468 |
-@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7z.lo `test -f '7z.c' || echo '$(srcdir)/'`7z.c |
|
1468 |
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7z_iface.lo `test -f '7z_iface.c' || echo '$(srcdir)/'`7z_iface.c |
|
1469 | 1469 |
|
1470 |
-libclamav_la-7zFile.lo: 7z/7zFile.c |
|
1471 |
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zFile.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zFile.Tpo -c -o libclamav_la-7zFile.lo `test -f '7z/7zFile.c' || echo '$(srcdir)/'`7z/7zFile.c |
|
1472 |
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-7zFile.Tpo $(DEPDIR)/libclamav_la-7zFile.Plo |
|
1470 |
+libclamav_la-7zAlloc.lo: 7z/7zAlloc.c |
|
1471 |
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zAlloc.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zAlloc.Tpo -c -o libclamav_la-7zAlloc.lo `test -f '7z/7zAlloc.c' || echo '$(srcdir)/'`7z/7zAlloc.c |
|
1472 |
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-7zAlloc.Tpo $(DEPDIR)/libclamav_la-7zAlloc.Plo |
|
1473 | 1473 |
@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ |
1474 |
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='7z/7zFile.c' object='libclamav_la-7zFile.lo' libtool=yes @AMDEPBACKSLASH@ |
|
1474 |
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='7z/7zAlloc.c' object='libclamav_la-7zAlloc.lo' libtool=yes @AMDEPBACKSLASH@ |
|
1475 | 1475 |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
1476 |
-@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zFile.lo `test -f '7z/7zFile.c' || echo '$(srcdir)/'`7z/7zFile.c |
|
1476 |
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zAlloc.lo `test -f '7z/7zAlloc.c' || echo '$(srcdir)/'`7z/7zAlloc.c |
|
1477 | 1477 |
|
1478 |
-libclamav_la-7zStream.lo: 7z/7zStream.c |
|
1479 |
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zStream.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zStream.Tpo -c -o libclamav_la-7zStream.lo `test -f '7z/7zStream.c' || echo '$(srcdir)/'`7z/7zStream.c |
|
1480 |
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-7zStream.Tpo $(DEPDIR)/libclamav_la-7zStream.Plo |
|
1478 |
+libclamav_la-7zBuf.lo: 7z/7zBuf.c |
|
1479 |
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zBuf.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zBuf.Tpo -c -o libclamav_la-7zBuf.lo `test -f '7z/7zBuf.c' || echo '$(srcdir)/'`7z/7zBuf.c |
|
1480 |
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-7zBuf.Tpo $(DEPDIR)/libclamav_la-7zBuf.Plo |
|
1481 | 1481 |
@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ |
1482 |
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='7z/7zStream.c' object='libclamav_la-7zStream.lo' libtool=yes @AMDEPBACKSLASH@ |
|
1482 |
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='7z/7zBuf.c' object='libclamav_la-7zBuf.lo' libtool=yes @AMDEPBACKSLASH@ |
|
1483 | 1483 |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
1484 |
-@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zStream.lo `test -f '7z/7zStream.c' || echo '$(srcdir)/'`7z/7zStream.c |
|
1484 |
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zBuf.lo `test -f '7z/7zBuf.c' || echo '$(srcdir)/'`7z/7zBuf.c |
|
1485 |
+ |
|
1486 |
+libclamav_la-7zBuf2.lo: 7z/7zBuf2.c |
|
1487 |
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zBuf2.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zBuf2.Tpo -c -o libclamav_la-7zBuf2.lo `test -f '7z/7zBuf2.c' || echo '$(srcdir)/'`7z/7zBuf2.c |
|
1488 |
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-7zBuf2.Tpo $(DEPDIR)/libclamav_la-7zBuf2.Plo |
|
1489 |
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ |
|
1490 |
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='7z/7zBuf2.c' object='libclamav_la-7zBuf2.lo' libtool=yes @AMDEPBACKSLASH@ |
|
1491 |
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
|
1492 |
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zBuf2.lo `test -f '7z/7zBuf2.c' || echo '$(srcdir)/'`7z/7zBuf2.c |
|
1485 | 1493 |
|
1486 | 1494 |
libclamav_la-7zCrc.lo: 7z/7zCrc.c |
1487 | 1495 |
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zCrc.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zCrc.Tpo -c -o libclamav_la-7zCrc.lo `test -f '7z/7zCrc.c' || echo '$(srcdir)/'`7z/7zCrc.c |
... | ... |
@@ -1491,13 +1491,37 @@ libclamav_la-7zCrc.lo: 7z/7zCrc.c |
1491 | 1491 |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
1492 | 1492 |
@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zCrc.lo `test -f '7z/7zCrc.c' || echo '$(srcdir)/'`7z/7zCrc.c |
1493 | 1493 |
|
1494 |
-libclamav_la-7zBuf.lo: 7z/7zBuf.c |
|
1495 |
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zBuf.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zBuf.Tpo -c -o libclamav_la-7zBuf.lo `test -f '7z/7zBuf.c' || echo '$(srcdir)/'`7z/7zBuf.c |
|
1496 |
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-7zBuf.Tpo $(DEPDIR)/libclamav_la-7zBuf.Plo |
|
1494 |
+libclamav_la-7zDec.lo: 7z/7zDec.c |
|
1495 |
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zDec.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zDec.Tpo -c -o libclamav_la-7zDec.lo `test -f '7z/7zDec.c' || echo '$(srcdir)/'`7z/7zDec.c |
|
1496 |
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-7zDec.Tpo $(DEPDIR)/libclamav_la-7zDec.Plo |
|
1497 | 1497 |
@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ |
1498 |
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='7z/7zBuf.c' object='libclamav_la-7zBuf.lo' libtool=yes @AMDEPBACKSLASH@ |
|
1498 |
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='7z/7zDec.c' object='libclamav_la-7zDec.lo' libtool=yes @AMDEPBACKSLASH@ |
|
1499 | 1499 |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
1500 |
-@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zBuf.lo `test -f '7z/7zBuf.c' || echo '$(srcdir)/'`7z/7zBuf.c |
|
1500 |
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zDec.lo `test -f '7z/7zDec.c' || echo '$(srcdir)/'`7z/7zDec.c |
|
1501 |
+ |
|
1502 |
+libclamav_la-7zFile.lo: 7z/7zFile.c |
|
1503 |
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zFile.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zFile.Tpo -c -o libclamav_la-7zFile.lo `test -f '7z/7zFile.c' || echo '$(srcdir)/'`7z/7zFile.c |
|
1504 |
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-7zFile.Tpo $(DEPDIR)/libclamav_la-7zFile.Plo |
|
1505 |
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ |
|
1506 |
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='7z/7zFile.c' object='libclamav_la-7zFile.lo' libtool=yes @AMDEPBACKSLASH@ |
|
1507 |
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
|
1508 |
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zFile.lo `test -f '7z/7zFile.c' || echo '$(srcdir)/'`7z/7zFile.c |
|
1509 |
+ |
|
1510 |
+libclamav_la-7zIn.lo: 7z/7zIn.c |
|
1511 |
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zIn.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zIn.Tpo -c -o libclamav_la-7zIn.lo `test -f '7z/7zIn.c' || echo '$(srcdir)/'`7z/7zIn.c |
|
1512 |
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-7zIn.Tpo $(DEPDIR)/libclamav_la-7zIn.Plo |
|
1513 |
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ |
|
1514 |
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='7z/7zIn.c' object='libclamav_la-7zIn.lo' libtool=yes @AMDEPBACKSLASH@ |
|
1515 |
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
|
1516 |
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zIn.lo `test -f '7z/7zIn.c' || echo '$(srcdir)/'`7z/7zIn.c |
|
1517 |
+ |
|
1518 |
+libclamav_la-7zStream.lo: 7z/7zStream.c |
|
1519 |
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zStream.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zStream.Tpo -c -o libclamav_la-7zStream.lo `test -f '7z/7zStream.c' || echo '$(srcdir)/'`7z/7zStream.c |
|
1520 |
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-7zStream.Tpo $(DEPDIR)/libclamav_la-7zStream.Plo |
|
1521 |
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ |
|
1522 |
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='7z/7zStream.c' object='libclamav_la-7zStream.lo' libtool=yes @AMDEPBACKSLASH@ |
|
1523 |
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
|
1524 |
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zStream.lo `test -f '7z/7zStream.c' || echo '$(srcdir)/'`7z/7zStream.c |
|
1501 | 1525 |
|
1502 | 1526 |
libclamav_la-Bcj2.lo: 7z/Bcj2.c |
1503 | 1527 |
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-Bcj2.lo -MD -MP -MF $(DEPDIR)/libclamav_la-Bcj2.Tpo -c -o libclamav_la-Bcj2.lo `test -f '7z/Bcj2.c' || echo '$(srcdir)/'`7z/Bcj2.c |
... | ... |
@@ -1523,45 +1547,37 @@ libclamav_la-Bra86.lo: 7z/Bra86.c |
1523 | 1523 |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
1524 | 1524 |
@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-Bra86.lo `test -f '7z/Bra86.c' || echo '$(srcdir)/'`7z/Bra86.c |
1525 | 1525 |
|
1526 |
-libclamav_la-7zIn.lo: 7z/Archive/7z/7zIn.c |
|
1527 |
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zIn.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zIn.Tpo -c -o libclamav_la-7zIn.lo `test -f '7z/Archive/7z/7zIn.c' || echo '$(srcdir)/'`7z/Archive/7z/7zIn.c |
|
1528 |
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-7zIn.Tpo $(DEPDIR)/libclamav_la-7zIn.Plo |
|
1526 |
+libclamav_la-Lzma2Dec.lo: 7z/Lzma2Dec.c |
|
1527 |
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-Lzma2Dec.lo -MD -MP -MF $(DEPDIR)/libclamav_la-Lzma2Dec.Tpo -c -o libclamav_la-Lzma2Dec.lo `test -f '7z/Lzma2Dec.c' || echo '$(srcdir)/'`7z/Lzma2Dec.c |
|
1528 |
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-Lzma2Dec.Tpo $(DEPDIR)/libclamav_la-Lzma2Dec.Plo |
|
1529 | 1529 |
@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ |
1530 |
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='7z/Archive/7z/7zIn.c' object='libclamav_la-7zIn.lo' libtool=yes @AMDEPBACKSLASH@ |
|
1530 |
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='7z/Lzma2Dec.c' object='libclamav_la-Lzma2Dec.lo' libtool=yes @AMDEPBACKSLASH@ |
|
1531 | 1531 |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
1532 |
-@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zIn.lo `test -f '7z/Archive/7z/7zIn.c' || echo '$(srcdir)/'`7z/Archive/7z/7zIn.c |
|
1532 |
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-Lzma2Dec.lo `test -f '7z/Lzma2Dec.c' || echo '$(srcdir)/'`7z/Lzma2Dec.c |
|
1533 | 1533 |
|
1534 |
-libclamav_la-7zDecode.lo: 7z/Archive/7z/7zDecode.c |
|
1535 |
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zDecode.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zDecode.Tpo -c -o libclamav_la-7zDecode.lo `test -f '7z/Archive/7z/7zDecode.c' || echo '$(srcdir)/'`7z/Archive/7z/7zDecode.c |
|
1536 |
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-7zDecode.Tpo $(DEPDIR)/libclamav_la-7zDecode.Plo |
|
1537 |
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ |
|
1538 |
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='7z/Archive/7z/7zDecode.c' object='libclamav_la-7zDecode.lo' libtool=yes @AMDEPBACKSLASH@ |
|
1539 |
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
|
1540 |
-@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zDecode.lo `test -f '7z/Archive/7z/7zDecode.c' || echo '$(srcdir)/'`7z/Archive/7z/7zDecode.c |
|
1541 |
- |
|
1542 |
-libclamav_la-7zItem.lo: 7z/Archive/7z/7zItem.c |
|
1543 |
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zItem.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zItem.Tpo -c -o libclamav_la-7zItem.lo `test -f '7z/Archive/7z/7zItem.c' || echo '$(srcdir)/'`7z/Archive/7z/7zItem.c |
|
1544 |
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-7zItem.Tpo $(DEPDIR)/libclamav_la-7zItem.Plo |
|
1534 |
+libclamav_la-LzmaDec.lo: 7z/LzmaDec.c |
|
1535 |
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-LzmaDec.lo -MD -MP -MF $(DEPDIR)/libclamav_la-LzmaDec.Tpo -c -o libclamav_la-LzmaDec.lo `test -f '7z/LzmaDec.c' || echo '$(srcdir)/'`7z/LzmaDec.c |
|
1536 |
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-LzmaDec.Tpo $(DEPDIR)/libclamav_la-LzmaDec.Plo |
|
1545 | 1537 |
@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ |
1546 |
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='7z/Archive/7z/7zItem.c' object='libclamav_la-7zItem.lo' libtool=yes @AMDEPBACKSLASH@ |
|
1538 |
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='7z/LzmaDec.c' object='libclamav_la-LzmaDec.lo' libtool=yes @AMDEPBACKSLASH@ |
|
1547 | 1539 |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
1548 |
-@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zItem.lo `test -f '7z/Archive/7z/7zItem.c' || echo '$(srcdir)/'`7z/Archive/7z/7zItem.c |
|
1540 |
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-LzmaDec.lo `test -f '7z/LzmaDec.c' || echo '$(srcdir)/'`7z/LzmaDec.c |
|
1549 | 1541 |
|
1550 |
-libclamav_la-7zHeader.lo: 7z/Archive/7z/7zHeader.c |
|
1551 |
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zHeader.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zHeader.Tpo -c -o libclamav_la-7zHeader.lo `test -f '7z/Archive/7z/7zHeader.c' || echo '$(srcdir)/'`7z/Archive/7z/7zHeader.c |
|
1552 |
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-7zHeader.Tpo $(DEPDIR)/libclamav_la-7zHeader.Plo |
|
1542 |
+libclamav_la-Ppmd7.lo: 7z/Ppmd7.c |
|
1543 |
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-Ppmd7.lo -MD -MP -MF $(DEPDIR)/libclamav_la-Ppmd7.Tpo -c -o libclamav_la-Ppmd7.lo `test -f '7z/Ppmd7.c' || echo '$(srcdir)/'`7z/Ppmd7.c |
|
1544 |
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-Ppmd7.Tpo $(DEPDIR)/libclamav_la-Ppmd7.Plo |
|
1553 | 1545 |
@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ |
1554 |
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='7z/Archive/7z/7zHeader.c' object='libclamav_la-7zHeader.lo' libtool=yes @AMDEPBACKSLASH@ |
|
1546 |
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='7z/Ppmd7.c' object='libclamav_la-Ppmd7.lo' libtool=yes @AMDEPBACKSLASH@ |
|
1555 | 1547 |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
1556 |
-@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zHeader.lo `test -f '7z/Archive/7z/7zHeader.c' || echo '$(srcdir)/'`7z/Archive/7z/7zHeader.c |
|
1548 |
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-Ppmd7.lo `test -f '7z/Ppmd7.c' || echo '$(srcdir)/'`7z/Ppmd7.c |
|
1557 | 1549 |
|
1558 |
-libclamav_la-7zExtract.lo: 7z/Archive/7z/7zExtract.c |
|
1559 |
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-7zExtract.lo -MD -MP -MF $(DEPDIR)/libclamav_la-7zExtract.Tpo -c -o libclamav_la-7zExtract.lo `test -f '7z/Archive/7z/7zExtract.c' || echo '$(srcdir)/'`7z/Archive/7z/7zExtract.c |
|
1560 |
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-7zExtract.Tpo $(DEPDIR)/libclamav_la-7zExtract.Plo |
|
1550 |
+libclamav_la-Ppmd7Dec.lo: 7z/Ppmd7Dec.c |
|
1551 |
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-Ppmd7Dec.lo -MD -MP -MF $(DEPDIR)/libclamav_la-Ppmd7Dec.Tpo -c -o libclamav_la-Ppmd7Dec.lo `test -f '7z/Ppmd7Dec.c' || echo '$(srcdir)/'`7z/Ppmd7Dec.c |
|
1552 |
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-Ppmd7Dec.Tpo $(DEPDIR)/libclamav_la-Ppmd7Dec.Plo |
|
1561 | 1553 |
@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ |
1562 |
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='7z/Archive/7z/7zExtract.c' object='libclamav_la-7zExtract.lo' libtool=yes @AMDEPBACKSLASH@ |
|
1554 |
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='7z/Ppmd7Dec.c' object='libclamav_la-Ppmd7Dec.lo' libtool=yes @AMDEPBACKSLASH@ |
|
1563 | 1555 |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
1564 |
-@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-7zExtract.lo `test -f '7z/Archive/7z/7zExtract.c' || echo '$(srcdir)/'`7z/Archive/7z/7zExtract.c |
|
1556 |
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-Ppmd7Dec.lo `test -f '7z/Ppmd7Dec.c' || echo '$(srcdir)/'`7z/Ppmd7Dec.c |
|
1565 | 1557 |
|
1566 | 1558 |
libclamav_la-explode.lo: explode.c |
1567 | 1559 |
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-explode.lo -MD -MP -MF $(DEPDIR)/libclamav_la-explode.Tpo -c -o libclamav_la-explode.lo `test -f 'explode.c' || echo '$(srcdir)/'`explode.c |
... | ... |
@@ -86,7 +86,7 @@ |
86 | 86 |
#include "cpio.h" |
87 | 87 |
#include "macho.h" |
88 | 88 |
#include "ishield.h" |
89 |
-#include "7z.h" |
|
89 |
+#include "7z_iface.h" |
|
90 | 90 |
#include "fmap.h" |
91 | 91 |
#include "cache.h" |
92 | 92 |
#include "events.h" |
... | ... |
@@ -2292,7 +2292,7 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
2292 | 2292 |
case CL_TYPE_7Z: |
2293 | 2293 |
ctx->container_type = CL_TYPE_7Z; |
2294 | 2294 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_7Z)) |
2295 |
- ret = cli_7unz(desc, ctx); |
|
2295 |
+ ret = cli_7unz(ctx); |
|
2296 | 2296 |
break; |
2297 | 2297 |
|
2298 | 2298 |
case CL_TYPE_POSIX_TAR: |