blob: 0cf22a52f5d4a9260ddc63ca486b585bebfa50c1 [file] [log] [blame]
Raph Leviendcecdd82012-03-23 11:21:16 -07001Index: test/lzma.cc
2===================================================================
3--- test/lzma.cc (revision 0)
4+++ test/lzma.cc (revision 0)
5@@ -0,0 +1,139 @@
6+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
7+// Use of this source code is governed by a BSD-style license that can be
8+// found in the LICENSE file.
9+
10+#include <arpa/inet.h>
11+#include <fcntl.h>
12+#include <sys/stat.h>
13+#include <unistd.h>
14+
15+#include <cstdio>
16+#include <string>
17+#include <vector>
18+
19+#include "opentype-sanitiser.h"
20+#include "ots-memory-stream.h"
21+
22+#include "third_party/lzma_sdk/LzmaLib.h"
23+
24+namespace {
25+
26+static const size_t kCompressedLengthFieldSize = 4;
27+
28+int Usage(const char *argv0) {
29+ std::fprintf(stderr, "Usage: %s (compress|decompress) filename\n", argv0);
30+ return 1;
31+}
32+
33+bool ReadFile(const char *file_name, std::vector<uint8_t>* data) {
34+ const int fd = open(file_name, O_RDONLY);
35+ if (fd < 0) {
36+ return false;
37+ }
38+
39+ struct stat st;
40+ fstat(fd, &st);
41+
42+ data->resize(st.st_size);
43+ if (read(fd, &(*data)[0], st.st_size) != st.st_size) {
44+ close(fd);
45+ return false;
46+ }
47+ close(fd);
48+ return true;
49+}
50+
51+bool Compress(std::vector<uint8_t>* input, std::vector<uint8_t>* output) {
52+ size_t props_size = LZMA_PROPS_SIZE;
53+ size_t out_len = input->size() * 2;
54+ output->resize(out_len + props_size + kCompressedLengthFieldSize);
55+
56+ uint8_t* output_start = &(*output)[kCompressedLengthFieldSize];
57+
58+ int result = LzmaCompress(output_start + LZMA_PROPS_SIZE, &out_len,
59+ &(*input)[0], input->size(),
60+ output_start, &props_size,
61+ -1, 0, -1, -1, -1, -1, 1);
62+ if (props_size != LZMA_PROPS_SIZE || result != SZ_OK)
63+ return false;
64+
65+ output->resize(props_size + out_len + kCompressedLengthFieldSize);
66+ // Store the uncompressed length at the beginning of buffer.
67+ uint32_t uncompressed_length = htonl(input->size());
68+ memcpy(&(*output)[0], &uncompressed_length, kCompressedLengthFieldSize);
69+ return true;
70+}
71+
72+bool Decompress(std::vector<uint8_t>* input, std::vector<uint8_t>* output) {
73+ if (input->size() < kCompressedLengthFieldSize + LZMA_PROPS_SIZE)
74+ return false;
75+
76+ // Assume the uncompressed length is stored at the beginning of the buffer
77+ // in network byte order.
78+ uint32_t uncompressed_length = 0;
79+ memcpy(&uncompressed_length, &(*input)[0], kCompressedLengthFieldSize);
80+ uncompressed_length = ntohl(uncompressed_length);
81+
82+ output->resize(uncompressed_length);
83+ uint8_t* input_start = &(*input)[kCompressedLengthFieldSize];
84+ size_t in_len = input->size() - LZMA_PROPS_SIZE;
85+ size_t out_len = output->size();
86+ int result = LzmaUncompress(&(*output)[0], &out_len,
87+ input_start + LZMA_PROPS_SIZE,
88+ &in_len, input_start, LZMA_PROPS_SIZE);
89+
90+ return result == SZ_OK;
91+}
92+
93+bool DumpResult(std::vector<uint8_t>* result, const std::string* file_name) {
94+ int fd = open(file_name->c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0600);
95+ if (fd < 0) {
96+ perror("opening output file");
97+ return false;
98+ }
99+ if (write(fd, &(*result)[0], result->size()) < 0) {
100+ perror("writing output file");
101+ close(fd);
102+ return false;
103+ }
104+ close(fd);
105+ return true;
106+}
107+
108+} // namespace
109+
110+int main(int argc, char** argv) {
111+ if (argc != 3) return Usage(argv[0]);
112+
113+ std::vector<uint8_t> in_data;
114+ if (!ReadFile(argv[2], &in_data)) {
115+ std::fprintf(stderr, "Failed to read file!\n");
116+ return 1;
117+ }
118+
119+ std::vector<uint8_t> out_data;
120+ std::string file_name;
121+ if (std::strncmp("compress", argv[1], 8) == 0) {
122+ if (!Compress(&in_data, &out_data)) {
123+ std::fprintf(stderr, "Failed to compress file.\n");
124+ return 1;
125+ }
126+ file_name = "compressed.dat";
127+ } else if (std::strncmp("decompress", argv[1], 10) == 0) {
128+ if (!Decompress(&in_data, &out_data)) {
129+ std::fprintf(stderr, "Failed to decompress file.\n");
130+ return 1;
131+ }
132+ file_name = "decompressed.dat";
133+ } else {
134+ std::fprintf(
135+ stderr,
136+ "The second argument must be either 'compress' or 'decompress'.");
137+ return 1;
138+ }
139+
140+ if (!DumpResult(&out_data, &file_name)) {
141+ std::fprintf(stderr, "Failed to write the result.\n");
142+ return 1;
143+ }
144+}
145
146Property changes on: test/lzma.cc
147___________________________________________________________________
148Added: svn:eol-style
149 + LF
150
151Index: ots-common.gypi
152===================================================================
153--- ots-common.gypi (revision 83)
154+++ ots-common.gypi (working copy)
155@@ -68,6 +68,7 @@
156 ],
157 'ots_include_dirs': [
158 'include',
159+ '.',
160 ],
161 },
162 }
163Index: ots-standalone.gyp
164===================================================================
165--- ots-standalone.gyp (revision 83)
166+++ ots-standalone.gyp (working copy)
167@@ -96,6 +96,12 @@
168 '<@(ots_include_dirs)',
169 ],
170 },
171+ 'dependencies': [
172+ 'third_party/lzma_sdk/lzma_sdk.gyp:lzma_sdk',
173+ ],
174+ 'export_dependent_settings': [
175+ 'third_party/lzma_sdk/lzma_sdk.gyp:lzma_sdk',
176+ ],
177 },
178 {
179 'target_name': 'idempotent',
180@@ -117,5 +123,15 @@
181 }],
182 ],
183 },
184+ {
185+ 'target_name': 'lzma',
186+ 'type': 'executable',
187+ 'sources': [
188+ 'test/lzma.cc',
189+ ],
190+ 'dependencies': [
191+ 'ots',
192+ ],
193+ },
194 ],
195 }
196Index: third_party/lzma_sdk/LzmaEnc.h
197===================================================================
198--- third_party/lzma_sdk/LzmaEnc.h (revision 0)
199+++ third_party/lzma_sdk/LzmaEnc.h (revision 0)
200@@ -0,0 +1,80 @@
201+/* LzmaEnc.h -- LZMA Encoder
202+2009-02-07 : Igor Pavlov : Public domain */
203+
204+#ifndef __LZMA_ENC_H
205+#define __LZMA_ENC_H
206+
207+#include "Types.h"
208+
209+#ifdef __cplusplus
210+extern "C" {
211+#endif
212+
213+#define LZMA_PROPS_SIZE 5
214+
215+typedef struct _CLzmaEncProps
216+{
217+ int level; /* 0 <= level <= 9 */
218+ UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
219+ (1 << 12) <= dictSize <= (1 << 30) for 64-bit version
220+ default = (1 << 24) */
221+ int lc; /* 0 <= lc <= 8, default = 3 */
222+ int lp; /* 0 <= lp <= 4, default = 0 */
223+ int pb; /* 0 <= pb <= 4, default = 2 */
224+ int algo; /* 0 - fast, 1 - normal, default = 1 */
225+ int fb; /* 5 <= fb <= 273, default = 32 */
226+ int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
227+ int numHashBytes; /* 2, 3 or 4, default = 4 */
228+ UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
229+ unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
230+ int numThreads; /* 1 or 2, default = 2 */
231+} CLzmaEncProps;
232+
233+void LzmaEncProps_Init(CLzmaEncProps *p);
234+void LzmaEncProps_Normalize(CLzmaEncProps *p);
235+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
236+
237+
238+/* ---------- CLzmaEncHandle Interface ---------- */
239+
240+/* LzmaEnc_* functions can return the following exit codes:
241+Returns:
242+ SZ_OK - OK
243+ SZ_ERROR_MEM - Memory allocation error
244+ SZ_ERROR_PARAM - Incorrect paramater in props
245+ SZ_ERROR_WRITE - Write callback error.
246+ SZ_ERROR_PROGRESS - some break from progress callback
247+ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
248+*/
249+
250+typedef void * CLzmaEncHandle;
251+
252+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
253+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
254+SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
255+SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
256+SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
257+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
258+SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
259+ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
260+
261+/* ---------- One Call Interface ---------- */
262+
263+/* LzmaEncode
264+Return code:
265+ SZ_OK - OK
266+ SZ_ERROR_MEM - Memory allocation error
267+ SZ_ERROR_PARAM - Incorrect paramater
268+ SZ_ERROR_OUTPUT_EOF - output buffer overflow
269+ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
270+*/
271+
272+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
273+ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
274+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
275+
276+#ifdef __cplusplus
277+}
278+#endif
279+
280+#endif
281
282Property changes on: third_party/lzma_sdk/LzmaEnc.h
283___________________________________________________________________
284Added: svn:eol-style
285 + LF
286
287Index: third_party/lzma_sdk/LzHash.h
288===================================================================
289--- third_party/lzma_sdk/LzHash.h (revision 0)
290+++ third_party/lzma_sdk/LzHash.h (revision 0)
291@@ -0,0 +1,54 @@
292+/* LzHash.h -- HASH functions for LZ algorithms
293+2009-02-07 : Igor Pavlov : Public domain */
294+
295+#ifndef __LZ_HASH_H
296+#define __LZ_HASH_H
297+
298+#define kHash2Size (1 << 10)
299+#define kHash3Size (1 << 16)
300+#define kHash4Size (1 << 20)
301+
302+#define kFix3HashSize (kHash2Size)
303+#define kFix4HashSize (kHash2Size + kHash3Size)
304+#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
305+
306+#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8);
307+
308+#define HASH3_CALC { \
309+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
310+ hash2Value = temp & (kHash2Size - 1); \
311+ hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
312+
313+#define HASH4_CALC { \
314+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
315+ hash2Value = temp & (kHash2Size - 1); \
316+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
317+ hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
318+
319+#define HASH5_CALC { \
320+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
321+ hash2Value = temp & (kHash2Size - 1); \
322+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
323+ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \
324+ hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \
325+ hash4Value &= (kHash4Size - 1); }
326+
327+/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
328+#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
329+
330+
331+#define MT_HASH2_CALC \
332+ hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
333+
334+#define MT_HASH3_CALC { \
335+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
336+ hash2Value = temp & (kHash2Size - 1); \
337+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
338+
339+#define MT_HASH4_CALC { \
340+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
341+ hash2Value = temp & (kHash2Size - 1); \
342+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
343+ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
344+
345+#endif
346
347Property changes on: third_party/lzma_sdk/LzHash.h
348___________________________________________________________________
349Added: svn:executable
350 + *
351Added: svn:eol-style
352 + LF
353
354Index: third_party/lzma_sdk/Alloc.h
355===================================================================
356--- third_party/lzma_sdk/Alloc.h (revision 0)
357+++ third_party/lzma_sdk/Alloc.h (revision 0)
358@@ -0,0 +1,38 @@
359+/* Alloc.h -- Memory allocation functions
360+2009-02-07 : Igor Pavlov : Public domain */
361+
362+#ifndef __COMMON_ALLOC_H
363+#define __COMMON_ALLOC_H
364+
365+#include <stddef.h>
366+
367+#ifdef __cplusplus
368+extern "C" {
369+#endif
370+
371+void *MyAlloc(size_t size);
372+void MyFree(void *address);
373+
374+#ifdef _WIN32
375+
376+void SetLargePageSize();
377+
378+void *MidAlloc(size_t size);
379+void MidFree(void *address);
380+void *BigAlloc(size_t size);
381+void BigFree(void *address);
382+
383+#else
384+
385+#define MidAlloc(size) MyAlloc(size)
386+#define MidFree(address) MyFree(address)
387+#define BigAlloc(size) MyAlloc(size)
388+#define BigFree(address) MyFree(address)
389+
390+#endif
391+
392+#ifdef __cplusplus
393+}
394+#endif
395+
396+#endif
397
398Property changes on: third_party/lzma_sdk/Alloc.h
399___________________________________________________________________
400Added: svn:eol-style
401 + LF
402
403Index: third_party/lzma_sdk/LzmaLib.h
404===================================================================
405--- third_party/lzma_sdk/LzmaLib.h (revision 0)
406+++ third_party/lzma_sdk/LzmaLib.h (revision 0)
407@@ -0,0 +1,135 @@
408+/* LzmaLib.h -- LZMA library interface
409+2009-04-07 : Igor Pavlov : Public domain */
410+
411+#ifndef __LZMA_LIB_H
412+#define __LZMA_LIB_H
413+
414+#include "Types.h"
415+
416+#ifdef __cplusplus
417+extern "C" {
418+#endif
419+
420+#define MY_STDAPI int MY_STD_CALL
421+
422+#define LZMA_PROPS_SIZE 5
423+
424+/*
425+RAM requirements for LZMA:
426+ for compression: (dictSize * 11.5 + 6 MB) + state_size
427+ for decompression: dictSize + state_size
428+ state_size = (4 + (1.5 << (lc + lp))) KB
429+ by default (lc=3, lp=0), state_size = 16 KB.
430+
431+LZMA properties (5 bytes) format
432+ Offset Size Description
433+ 0 1 lc, lp and pb in encoded form.
434+ 1 4 dictSize (little endian).
435+*/
436+
437+/*
438+LzmaCompress
439+------------
440+
441+outPropsSize -
442+ In: the pointer to the size of outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.
443+ Out: the pointer to the size of written properties in outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.
444+
445+ LZMA Encoder will use defult values for any parameter, if it is
446+ -1 for any from: level, loc, lp, pb, fb, numThreads
447+ 0 for dictSize
448+
449+level - compression level: 0 <= level <= 9;
450+
451+ level dictSize algo fb
452+ 0: 16 KB 0 32
453+ 1: 64 KB 0 32
454+ 2: 256 KB 0 32
455+ 3: 1 MB 0 32
456+ 4: 4 MB 0 32
457+ 5: 16 MB 1 32
458+ 6: 32 MB 1 32
459+ 7+: 64 MB 1 64
460+
461+ The default value for "level" is 5.
462+
463+ algo = 0 means fast method
464+ algo = 1 means normal method
465+
466+dictSize - The dictionary size in bytes. The maximum value is
467+ 128 MB = (1 << 27) bytes for 32-bit version
468+ 1 GB = (1 << 30) bytes for 64-bit version
469+ The default value is 16 MB = (1 << 24) bytes.
470+ It's recommended to use the dictionary that is larger than 4 KB and
471+ that can be calculated as (1 << N) or (3 << N) sizes.
472+
473+lc - The number of literal context bits (high bits of previous literal).
474+ It can be in the range from 0 to 8. The default value is 3.
475+ Sometimes lc=4 gives the gain for big files.
476+
477+lp - The number of literal pos bits (low bits of current position for literals).
478+ It can be in the range from 0 to 4. The default value is 0.
479+ The lp switch is intended for periodical data when the period is equal to 2^lp.
480+ For example, for 32-bit (4 bytes) periodical data you can use lp=2. Often it's
481+ better to set lc=0, if you change lp switch.
482+
483+pb - The number of pos bits (low bits of current position).
484+ It can be in the range from 0 to 4. The default value is 2.
485+ The pb switch is intended for periodical data when the period is equal 2^pb.
486+
487+fb - Word size (the number of fast bytes).
488+ It can be in the range from 5 to 273. The default value is 32.
489+ Usually, a big number gives a little bit better compression ratio and
490+ slower compression process.
491+
492+numThreads - The number of thereads. 1 or 2. The default value is 2.
493+ Fast mode (algo = 0) can use only 1 thread.
494+
495+Out:
496+ destLen - processed output size
497+Returns:
498+ SZ_OK - OK
499+ SZ_ERROR_MEM - Memory allocation error
500+ SZ_ERROR_PARAM - Incorrect paramater
501+ SZ_ERROR_OUTPUT_EOF - output buffer overflow
502+ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
503+*/
504+
505+MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
506+ unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */
507+ int level, /* 0 <= level <= 9, default = 5 */
508+ unsigned dictSize, /* default = (1 << 24) */
509+ int lc, /* 0 <= lc <= 8, default = 3 */
510+ int lp, /* 0 <= lp <= 4, default = 0 */
511+ int pb, /* 0 <= pb <= 4, default = 2 */
512+ int fb, /* 5 <= fb <= 273, default = 32 */
513+ int numThreads /* 1 or 2, default = 2 */
514+ );
515+
516+/*
517+LzmaUncompress
518+--------------
519+In:
520+ dest - output data
521+ destLen - output data size
522+ src - input data
523+ srcLen - input data size
524+Out:
525+ destLen - processed output size
526+ srcLen - processed input size
527+Returns:
528+ SZ_OK - OK
529+ SZ_ERROR_DATA - Data error
530+ SZ_ERROR_MEM - Memory allocation arror
531+ SZ_ERROR_UNSUPPORTED - Unsupported properties
532+ SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src)
533+*/
534+
535+MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen,
536+ const unsigned char *props, size_t propsSize);
537+
538+#ifdef __cplusplus
539+}
540+#endif
541+
542+#endif
543
544Property changes on: third_party/lzma_sdk/LzmaLib.h
545___________________________________________________________________
546Added: svn:eol-style
547 + LF
548
549Index: third_party/lzma_sdk/LICENSE
550===================================================================
551--- third_party/lzma_sdk/LICENSE (revision 0)
552+++ third_party/lzma_sdk/LICENSE (revision 0)
553@@ -0,0 +1 @@
554+LZMA SDK is placed in the public domain.
555Index: third_party/lzma_sdk/Types.h
556===================================================================
557--- third_party/lzma_sdk/Types.h (revision 0)
558+++ third_party/lzma_sdk/Types.h (revision 0)
559@@ -0,0 +1,254 @@
560+/* Types.h -- Basic types
561+2010-10-09 : Igor Pavlov : Public domain */
562+
563+#ifndef __7Z_TYPES_H
564+#define __7Z_TYPES_H
565+
566+#include <stddef.h>
567+
568+#ifdef _WIN32
569+#include <windows.h>
570+#endif
571+
572+#ifndef EXTERN_C_BEGIN
573+#ifdef __cplusplus
574+#define EXTERN_C_BEGIN extern "C" {
575+#define EXTERN_C_END }
576+#else
577+#define EXTERN_C_BEGIN
578+#define EXTERN_C_END
579+#endif
580+#endif
581+
582+EXTERN_C_BEGIN
583+
584+#define SZ_OK 0
585+
586+#define SZ_ERROR_DATA 1
587+#define SZ_ERROR_MEM 2
588+#define SZ_ERROR_CRC 3
589+#define SZ_ERROR_UNSUPPORTED 4
590+#define SZ_ERROR_PARAM 5
591+#define SZ_ERROR_INPUT_EOF 6
592+#define SZ_ERROR_OUTPUT_EOF 7
593+#define SZ_ERROR_READ 8
594+#define SZ_ERROR_WRITE 9
595+#define SZ_ERROR_PROGRESS 10
596+#define SZ_ERROR_FAIL 11
597+#define SZ_ERROR_THREAD 12
598+
599+#define SZ_ERROR_ARCHIVE 16
600+#define SZ_ERROR_NO_ARCHIVE 17
601+
602+typedef int SRes;
603+
604+#ifdef _WIN32
605+typedef DWORD WRes;
606+#else
607+typedef int WRes;
608+#endif
609+
610+#ifndef RINOK
611+#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
612+#endif
613+
614+typedef unsigned char Byte;
615+typedef short Int16;
616+typedef unsigned short UInt16;
617+
618+#ifdef _LZMA_UINT32_IS_ULONG
619+typedef long Int32;
620+typedef unsigned long UInt32;
621+#else
622+typedef int Int32;
623+typedef unsigned int UInt32;
624+#endif
625+
626+#ifdef _SZ_NO_INT_64
627+
628+/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
629+ NOTES: Some code will work incorrectly in that case! */
630+
631+typedef long Int64;
632+typedef unsigned long UInt64;
633+
634+#else
635+
636+#if defined(_MSC_VER) || defined(__BORLANDC__)
637+typedef __int64 Int64;
638+typedef unsigned __int64 UInt64;
639+#define UINT64_CONST(n) n
640+#else
641+typedef long long int Int64;
642+typedef unsigned long long int UInt64;
643+#define UINT64_CONST(n) n ## ULL
644+#endif
645+
646+#endif
647+
648+#ifdef _LZMA_NO_SYSTEM_SIZE_T
649+typedef UInt32 SizeT;
650+#else
651+typedef size_t SizeT;
652+#endif
653+
654+typedef int Bool;
655+#define True 1
656+#define False 0
657+
658+
659+#ifdef _WIN32
660+#define MY_STD_CALL __stdcall
661+#else
662+#define MY_STD_CALL
663+#endif
664+
665+#ifdef _MSC_VER
666+
667+#if _MSC_VER >= 1300
668+#define MY_NO_INLINE __declspec(noinline)
669+#else
670+#define MY_NO_INLINE
671+#endif
672+
673+#define MY_CDECL __cdecl
674+#define MY_FAST_CALL __fastcall
675+
676+#else
677+
678+#define MY_CDECL
679+#define MY_FAST_CALL
680+
681+#endif
682+
683+
684+/* The following interfaces use first parameter as pointer to structure */
685+
686+typedef struct
687+{
688+ Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
689+} IByteIn;
690+
691+typedef struct
692+{
693+ void (*Write)(void *p, Byte b);
694+} IByteOut;
695+
696+typedef struct
697+{
698+ SRes (*Read)(void *p, void *buf, size_t *size);
699+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
700+ (output(*size) < input(*size)) is allowed */
701+} ISeqInStream;
702+
703+/* it can return SZ_ERROR_INPUT_EOF */
704+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
705+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
706+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
707+
708+typedef struct
709+{
710+ size_t (*Write)(void *p, const void *buf, size_t size);
711+ /* Returns: result - the number of actually written bytes.
712+ (result < size) means error */
713+} ISeqOutStream;
714+
715+typedef enum
716+{
717+ SZ_SEEK_SET = 0,
718+ SZ_SEEK_CUR = 1,
719+ SZ_SEEK_END = 2
720+} ESzSeek;
721+
722+typedef struct
723+{
724+ SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
725+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
726+} ISeekInStream;
727+
728+typedef struct
729+{
730+ SRes (*Look)(void *p, const void **buf, size_t *size);
731+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
732+ (output(*size) > input(*size)) is not allowed
733+ (output(*size) < input(*size)) is allowed */
734+ SRes (*Skip)(void *p, size_t offset);
735+ /* offset must be <= output(*size) of Look */
736+
737+ SRes (*Read)(void *p, void *buf, size_t *size);
738+ /* reads directly (without buffer). It's same as ISeqInStream::Read */
739+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
740+} ILookInStream;
741+
742+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
743+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
744+
745+/* reads via ILookInStream::Read */
746+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
747+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
748+
749+#define LookToRead_BUF_SIZE (1 << 14)
750+
751+typedef struct
752+{
753+ ILookInStream s;
754+ ISeekInStream *realStream;
755+ size_t pos;
756+ size_t size;
757+ Byte buf[LookToRead_BUF_SIZE];
758+} CLookToRead;
759+
760+void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
761+void LookToRead_Init(CLookToRead *p);
762+
763+typedef struct
764+{
765+ ISeqInStream s;
766+ ILookInStream *realStream;
767+} CSecToLook;
768+
769+void SecToLook_CreateVTable(CSecToLook *p);
770+
771+typedef struct
772+{
773+ ISeqInStream s;
774+ ILookInStream *realStream;
775+} CSecToRead;
776+
777+void SecToRead_CreateVTable(CSecToRead *p);
778+
779+typedef struct
780+{
781+ SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
782+ /* Returns: result. (result != SZ_OK) means break.
783+ Value (UInt64)(Int64)-1 for size means unknown value. */
784+} ICompressProgress;
785+
786+typedef struct
787+{
788+ void *(*Alloc)(void *p, size_t size);
789+ void (*Free)(void *p, void *address); /* address can be 0 */
790+} ISzAlloc;
791+
792+#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
793+#define IAlloc_Free(p, a) (p)->Free((p), a)
794+
795+#ifdef _WIN32
796+
797+#define CHAR_PATH_SEPARATOR '\\'
798+#define WCHAR_PATH_SEPARATOR L'\\'
799+#define STRING_PATH_SEPARATOR "\\"
800+#define WSTRING_PATH_SEPARATOR L"\\"
801+
802+#else
803+
804+#define CHAR_PATH_SEPARATOR '/'
805+#define WCHAR_PATH_SEPARATOR L'/'
806+#define STRING_PATH_SEPARATOR "/"
807+#define WSTRING_PATH_SEPARATOR L"/"
808+
809+#endif
810+
811+EXTERN_C_END
812+
813+#endif
814
815Property changes on: third_party/lzma_sdk/Types.h
816___________________________________________________________________
817Added: svn:eol-style
818 + LF
819
820Index: third_party/lzma_sdk/LzmaDec.c
821===================================================================
822--- third_party/lzma_sdk/LzmaDec.c (revision 0)
823+++ third_party/lzma_sdk/LzmaDec.c (revision 0)
824@@ -0,0 +1,999 @@
825+/* LzmaDec.c -- LZMA Decoder
826+2009-09-20 : Igor Pavlov : Public domain */
827+
828+#include "LzmaDec.h"
829+
830+#include <string.h>
831+
832+#define kNumTopBits 24
833+#define kTopValue ((UInt32)1 << kNumTopBits)
834+
835+#define kNumBitModelTotalBits 11
836+#define kBitModelTotal (1 << kNumBitModelTotalBits)
837+#define kNumMoveBits 5
838+
839+#define RC_INIT_SIZE 5
840+
841+#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
842+
843+#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
844+#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
845+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
846+#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
847+ { UPDATE_0(p); i = (i + i); A0; } else \
848+ { UPDATE_1(p); i = (i + i) + 1; A1; }
849+#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
850+
851+#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
852+#define TREE_DECODE(probs, limit, i) \
853+ { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
854+
855+/* #define _LZMA_SIZE_OPT */
856+
857+#ifdef _LZMA_SIZE_OPT
858+#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
859+#else
860+#define TREE_6_DECODE(probs, i) \
861+ { i = 1; \
862+ TREE_GET_BIT(probs, i); \
863+ TREE_GET_BIT(probs, i); \
864+ TREE_GET_BIT(probs, i); \
865+ TREE_GET_BIT(probs, i); \
866+ TREE_GET_BIT(probs, i); \
867+ TREE_GET_BIT(probs, i); \
868+ i -= 0x40; }
869+#endif
870+
871+#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
872+
873+#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
874+#define UPDATE_0_CHECK range = bound;
875+#define UPDATE_1_CHECK range -= bound; code -= bound;
876+#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
877+ { UPDATE_0_CHECK; i = (i + i); A0; } else \
878+ { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
879+#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
880+#define TREE_DECODE_CHECK(probs, limit, i) \
881+ { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
882+
883+
884+#define kNumPosBitsMax 4
885+#define kNumPosStatesMax (1 << kNumPosBitsMax)
886+
887+#define kLenNumLowBits 3
888+#define kLenNumLowSymbols (1 << kLenNumLowBits)
889+#define kLenNumMidBits 3
890+#define kLenNumMidSymbols (1 << kLenNumMidBits)
891+#define kLenNumHighBits 8
892+#define kLenNumHighSymbols (1 << kLenNumHighBits)
893+
894+#define LenChoice 0
895+#define LenChoice2 (LenChoice + 1)
896+#define LenLow (LenChoice2 + 1)
897+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
898+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
899+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
900+
901+
902+#define kNumStates 12
903+#define kNumLitStates 7
904+
905+#define kStartPosModelIndex 4
906+#define kEndPosModelIndex 14
907+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
908+
909+#define kNumPosSlotBits 6
910+#define kNumLenToPosStates 4
911+
912+#define kNumAlignBits 4
913+#define kAlignTableSize (1 << kNumAlignBits)
914+
915+#define kMatchMinLen 2
916+#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
917+
918+#define IsMatch 0
919+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
920+#define IsRepG0 (IsRep + kNumStates)
921+#define IsRepG1 (IsRepG0 + kNumStates)
922+#define IsRepG2 (IsRepG1 + kNumStates)
923+#define IsRep0Long (IsRepG2 + kNumStates)
924+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
925+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
926+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
927+#define LenCoder (Align + kAlignTableSize)
928+#define RepLenCoder (LenCoder + kNumLenProbs)
929+#define Literal (RepLenCoder + kNumLenProbs)
930+
931+#define LZMA_BASE_SIZE 1846
932+#define LZMA_LIT_SIZE 768
933+
934+#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
935+
936+#if Literal != LZMA_BASE_SIZE
937+StopCompilingDueBUG
938+#endif
939+
940+#define LZMA_DIC_MIN (1 << 12)
941+
942+/* First LZMA-symbol is always decoded.
943+And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
944+Out:
945+ Result:
946+ SZ_OK - OK
947+ SZ_ERROR_DATA - Error
948+ p->remainLen:
949+ < kMatchSpecLenStart : normal remain
950+ = kMatchSpecLenStart : finished
951+ = kMatchSpecLenStart + 1 : Flush marker
952+ = kMatchSpecLenStart + 2 : State Init Marker
953+*/
954+
955+static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
956+{
957+ CLzmaProb *probs = p->probs;
958+
959+ unsigned state = p->state;
960+ UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
961+ unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
962+ unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
963+ unsigned lc = p->prop.lc;
964+
965+ Byte *dic = p->dic;
966+ SizeT dicBufSize = p->dicBufSize;
967+ SizeT dicPos = p->dicPos;
968+
969+ UInt32 processedPos = p->processedPos;
970+ UInt32 checkDicSize = p->checkDicSize;
971+ unsigned len = 0;
972+
973+ const Byte *buf = p->buf;
974+ UInt32 range = p->range;
975+ UInt32 code = p->code;
976+
977+ do
978+ {
979+ CLzmaProb *prob;
980+ UInt32 bound;
981+ unsigned ttt;
982+ unsigned posState = processedPos & pbMask;
983+
984+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
985+ IF_BIT_0(prob)
986+ {
987+ unsigned symbol;
988+ UPDATE_0(prob);
989+ prob = probs + Literal;
990+ if (checkDicSize != 0 || processedPos != 0)
991+ prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
992+ (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
993+
994+ if (state < kNumLitStates)
995+ {
996+ state -= (state < 4) ? state : 3;
997+ symbol = 1;
998+ do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
999+ }
1000+ else
1001+ {
1002+ unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
1003+ unsigned offs = 0x100;
1004+ state -= (state < 10) ? 3 : 6;
1005+ symbol = 1;
1006+ do
1007+ {
1008+ unsigned bit;
1009+ CLzmaProb *probLit;
1010+ matchByte <<= 1;
1011+ bit = (matchByte & offs);
1012+ probLit = prob + offs + bit + symbol;
1013+ GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
1014+ }
1015+ while (symbol < 0x100);
1016+ }
1017+ dic[dicPos++] = (Byte)symbol;
1018+ processedPos++;
1019+ continue;
1020+ }
1021+ else
1022+ {
1023+ UPDATE_1(prob);
1024+ prob = probs + IsRep + state;
1025+ IF_BIT_0(prob)
1026+ {
1027+ UPDATE_0(prob);
1028+ state += kNumStates;
1029+ prob = probs + LenCoder;
1030+ }
1031+ else
1032+ {
1033+ UPDATE_1(prob);
1034+ if (checkDicSize == 0 && processedPos == 0)
1035+ return SZ_ERROR_DATA;
1036+ prob = probs + IsRepG0 + state;
1037+ IF_BIT_0(prob)
1038+ {
1039+ UPDATE_0(prob);
1040+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
1041+ IF_BIT_0(prob)
1042+ {
1043+ UPDATE_0(prob);
1044+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
1045+ dicPos++;
1046+ processedPos++;
1047+ state = state < kNumLitStates ? 9 : 11;
1048+ continue;
1049+ }
1050+ UPDATE_1(prob);
1051+ }
1052+ else
1053+ {
1054+ UInt32 distance;
1055+ UPDATE_1(prob);
1056+ prob = probs + IsRepG1 + state;
1057+ IF_BIT_0(prob)
1058+ {
1059+ UPDATE_0(prob);
1060+ distance = rep1;
1061+ }
1062+ else
1063+ {
1064+ UPDATE_1(prob);
1065+ prob = probs + IsRepG2 + state;
1066+ IF_BIT_0(prob)
1067+ {
1068+ UPDATE_0(prob);
1069+ distance = rep2;
1070+ }
1071+ else
1072+ {
1073+ UPDATE_1(prob);
1074+ distance = rep3;
1075+ rep3 = rep2;
1076+ }
1077+ rep2 = rep1;
1078+ }
1079+ rep1 = rep0;
1080+ rep0 = distance;
1081+ }
1082+ state = state < kNumLitStates ? 8 : 11;
1083+ prob = probs + RepLenCoder;
1084+ }
1085+ {
1086+ unsigned limit, offset;
1087+ CLzmaProb *probLen = prob + LenChoice;
1088+ IF_BIT_0(probLen)
1089+ {
1090+ UPDATE_0(probLen);
1091+ probLen = prob + LenLow + (posState << kLenNumLowBits);
1092+ offset = 0;
1093+ limit = (1 << kLenNumLowBits);
1094+ }
1095+ else
1096+ {
1097+ UPDATE_1(probLen);
1098+ probLen = prob + LenChoice2;
1099+ IF_BIT_0(probLen)
1100+ {
1101+ UPDATE_0(probLen);
1102+ probLen = prob + LenMid + (posState << kLenNumMidBits);
1103+ offset = kLenNumLowSymbols;
1104+ limit = (1 << kLenNumMidBits);
1105+ }
1106+ else
1107+ {
1108+ UPDATE_1(probLen);
1109+ probLen = prob + LenHigh;
1110+ offset = kLenNumLowSymbols + kLenNumMidSymbols;
1111+ limit = (1 << kLenNumHighBits);
1112+ }
1113+ }
1114+ TREE_DECODE(probLen, limit, len);
1115+ len += offset;
1116+ }
1117+
1118+ if (state >= kNumStates)
1119+ {
1120+ UInt32 distance;
1121+ prob = probs + PosSlot +
1122+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
1123+ TREE_6_DECODE(prob, distance);
1124+ if (distance >= kStartPosModelIndex)
1125+ {
1126+ unsigned posSlot = (unsigned)distance;
1127+ int numDirectBits = (int)(((distance >> 1) - 1));
1128+ distance = (2 | (distance & 1));
1129+ if (posSlot < kEndPosModelIndex)
1130+ {
1131+ distance <<= numDirectBits;
1132+ prob = probs + SpecPos + distance - posSlot - 1;
1133+ {
1134+ UInt32 mask = 1;
1135+ unsigned i = 1;
1136+ do
1137+ {
1138+ GET_BIT2(prob + i, i, ; , distance |= mask);
1139+ mask <<= 1;
1140+ }
1141+ while (--numDirectBits != 0);
1142+ }
1143+ }
1144+ else
1145+ {
1146+ numDirectBits -= kNumAlignBits;
1147+ do
1148+ {
1149+ NORMALIZE
1150+ range >>= 1;
1151+
1152+ {
1153+ UInt32 t;
1154+ code -= range;
1155+ t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
1156+ distance = (distance << 1) + (t + 1);
1157+ code += range & t;
1158+ }
1159+ /*
1160+ distance <<= 1;
1161+ if (code >= range)
1162+ {
1163+ code -= range;
1164+ distance |= 1;
1165+ }
1166+ */
1167+ }
1168+ while (--numDirectBits != 0);
1169+ prob = probs + Align;
1170+ distance <<= kNumAlignBits;
1171+ {
1172+ unsigned i = 1;
1173+ GET_BIT2(prob + i, i, ; , distance |= 1);
1174+ GET_BIT2(prob + i, i, ; , distance |= 2);
1175+ GET_BIT2(prob + i, i, ; , distance |= 4);
1176+ GET_BIT2(prob + i, i, ; , distance |= 8);
1177+ }
1178+ if (distance == (UInt32)0xFFFFFFFF)
1179+ {
1180+ len += kMatchSpecLenStart;
1181+ state -= kNumStates;
1182+ break;
1183+ }
1184+ }
1185+ }
1186+ rep3 = rep2;
1187+ rep2 = rep1;
1188+ rep1 = rep0;
1189+ rep0 = distance + 1;
1190+ if (checkDicSize == 0)
1191+ {
1192+ if (distance >= processedPos)
1193+ return SZ_ERROR_DATA;
1194+ }
1195+ else if (distance >= checkDicSize)
1196+ return SZ_ERROR_DATA;
1197+ state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
1198+ }
1199+
1200+ len += kMatchMinLen;
1201+
1202+ if (limit == dicPos)
1203+ return SZ_ERROR_DATA;
1204+ {
1205+ SizeT rem = limit - dicPos;
1206+ unsigned curLen = ((rem < len) ? (unsigned)rem : len);
1207+ SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
1208+
1209+ processedPos += curLen;
1210+
1211+ len -= curLen;
1212+ if (pos + curLen <= dicBufSize)
1213+ {
1214+ Byte *dest = dic + dicPos;
1215+ ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
1216+ const Byte *lim = dest + curLen;
1217+ dicPos += curLen;
1218+ do
1219+ *(dest) = (Byte)*(dest + src);
1220+ while (++dest != lim);
1221+ }
1222+ else
1223+ {
1224+ do
1225+ {
1226+ dic[dicPos++] = dic[pos];
1227+ if (++pos == dicBufSize)
1228+ pos = 0;
1229+ }
1230+ while (--curLen != 0);
1231+ }
1232+ }
1233+ }
1234+ }
1235+ while (dicPos < limit && buf < bufLimit);
1236+ NORMALIZE;
1237+ p->buf = buf;
1238+ p->range = range;
1239+ p->code = code;
1240+ p->remainLen = len;
1241+ p->dicPos = dicPos;
1242+ p->processedPos = processedPos;
1243+ p->reps[0] = rep0;
1244+ p->reps[1] = rep1;
1245+ p->reps[2] = rep2;
1246+ p->reps[3] = rep3;
1247+ p->state = state;
1248+
1249+ return SZ_OK;
1250+}
1251+
1252+static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
1253+{
1254+ if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
1255+ {
1256+ Byte *dic = p->dic;
1257+ SizeT dicPos = p->dicPos;
1258+ SizeT dicBufSize = p->dicBufSize;
1259+ unsigned len = p->remainLen;
1260+ UInt32 rep0 = p->reps[0];
1261+ if (limit - dicPos < len)
1262+ len = (unsigned)(limit - dicPos);
1263+
1264+ if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
1265+ p->checkDicSize = p->prop.dicSize;
1266+
1267+ p->processedPos += len;
1268+ p->remainLen -= len;
1269+ while (len-- != 0)
1270+ {
1271+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
1272+ dicPos++;
1273+ }
1274+ p->dicPos = dicPos;
1275+ }
1276+}
1277+
1278+static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
1279+{
1280+ do
1281+ {
1282+ SizeT limit2 = limit;
1283+ if (p->checkDicSize == 0)
1284+ {
1285+ UInt32 rem = p->prop.dicSize - p->processedPos;
1286+ if (limit - p->dicPos > rem)
1287+ limit2 = p->dicPos + rem;
1288+ }
1289+ RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
1290+ if (p->processedPos >= p->prop.dicSize)
1291+ p->checkDicSize = p->prop.dicSize;
1292+ LzmaDec_WriteRem(p, limit);
1293+ }
1294+ while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
1295+
1296+ if (p->remainLen > kMatchSpecLenStart)
1297+ {
1298+ p->remainLen = kMatchSpecLenStart;
1299+ }
1300+ return 0;
1301+}
1302+
1303+typedef enum
1304+{
1305+ DUMMY_ERROR, /* unexpected end of input stream */
1306+ DUMMY_LIT,
1307+ DUMMY_MATCH,
1308+ DUMMY_REP
1309+} ELzmaDummy;
1310+
1311+static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
1312+{
1313+ UInt32 range = p->range;
1314+ UInt32 code = p->code;
1315+ const Byte *bufLimit = buf + inSize;
1316+ CLzmaProb *probs = p->probs;
1317+ unsigned state = p->state;
1318+ ELzmaDummy res;
1319+
1320+ {
1321+ CLzmaProb *prob;
1322+ UInt32 bound;
1323+ unsigned ttt;
1324+ unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
1325+
1326+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
1327+ IF_BIT_0_CHECK(prob)
1328+ {
1329+ UPDATE_0_CHECK
1330+
1331+ /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
1332+
1333+ prob = probs + Literal;
1334+ if (p->checkDicSize != 0 || p->processedPos != 0)
1335+ prob += (LZMA_LIT_SIZE *
1336+ ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
1337+ (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
1338+
1339+ if (state < kNumLitStates)
1340+ {
1341+ unsigned symbol = 1;
1342+ do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
1343+ }
1344+ else
1345+ {
1346+ unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
1347+ ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
1348+ unsigned offs = 0x100;
1349+ unsigned symbol = 1;
1350+ do
1351+ {
1352+ unsigned bit;
1353+ CLzmaProb *probLit;
1354+ matchByte <<= 1;
1355+ bit = (matchByte & offs);
1356+ probLit = prob + offs + bit + symbol;
1357+ GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
1358+ }
1359+ while (symbol < 0x100);
1360+ }
1361+ res = DUMMY_LIT;
1362+ }
1363+ else
1364+ {
1365+ unsigned len;
1366+ UPDATE_1_CHECK;
1367+
1368+ prob = probs + IsRep + state;
1369+ IF_BIT_0_CHECK(prob)
1370+ {
1371+ UPDATE_0_CHECK;
1372+ state = 0;
1373+ prob = probs + LenCoder;
1374+ res = DUMMY_MATCH;
1375+ }
1376+ else
1377+ {
1378+ UPDATE_1_CHECK;
1379+ res = DUMMY_REP;
1380+ prob = probs + IsRepG0 + state;
1381+ IF_BIT_0_CHECK(prob)
1382+ {
1383+ UPDATE_0_CHECK;
1384+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
1385+ IF_BIT_0_CHECK(prob)
1386+ {
1387+ UPDATE_0_CHECK;
1388+ NORMALIZE_CHECK;
1389+ return DUMMY_REP;
1390+ }
1391+ else
1392+ {
1393+ UPDATE_1_CHECK;
1394+ }
1395+ }
1396+ else
1397+ {
1398+ UPDATE_1_CHECK;
1399+ prob = probs + IsRepG1 + state;
1400+ IF_BIT_0_CHECK(prob)
1401+ {
1402+ UPDATE_0_CHECK;
1403+ }
1404+ else
1405+ {
1406+ UPDATE_1_CHECK;
1407+ prob = probs + IsRepG2 + state;
1408+ IF_BIT_0_CHECK(prob)
1409+ {
1410+ UPDATE_0_CHECK;
1411+ }
1412+ else
1413+ {
1414+ UPDATE_1_CHECK;
1415+ }
1416+ }
1417+ }
1418+ state = kNumStates;
1419+ prob = probs + RepLenCoder;
1420+ }
1421+ {
1422+ unsigned limit, offset;
1423+ CLzmaProb *probLen = prob + LenChoice;
1424+ IF_BIT_0_CHECK(probLen)
1425+ {
1426+ UPDATE_0_CHECK;
1427+ probLen = prob + LenLow + (posState << kLenNumLowBits);
1428+ offset = 0;
1429+ limit = 1 << kLenNumLowBits;
1430+ }
1431+ else
1432+ {
1433+ UPDATE_1_CHECK;
1434+ probLen = prob + LenChoice2;
1435+ IF_BIT_0_CHECK(probLen)
1436+ {
1437+ UPDATE_0_CHECK;
1438+ probLen = prob + LenMid + (posState << kLenNumMidBits);
1439+ offset = kLenNumLowSymbols;
1440+ limit = 1 << kLenNumMidBits;
1441+ }
1442+ else
1443+ {
1444+ UPDATE_1_CHECK;
1445+ probLen = prob + LenHigh;
1446+ offset = kLenNumLowSymbols + kLenNumMidSymbols;
1447+ limit = 1 << kLenNumHighBits;
1448+ }
1449+ }
1450+ TREE_DECODE_CHECK(probLen, limit, len);
1451+ len += offset;
1452+ }
1453+
1454+ if (state < 4)
1455+ {
1456+ unsigned posSlot;
1457+ prob = probs + PosSlot +
1458+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
1459+ kNumPosSlotBits);
1460+ TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
1461+ if (posSlot >= kStartPosModelIndex)
1462+ {
1463+ int numDirectBits = ((posSlot >> 1) - 1);
1464+
1465+ /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
1466+
1467+ if (posSlot < kEndPosModelIndex)
1468+ {
1469+ prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
1470+ }
1471+ else
1472+ {
1473+ numDirectBits -= kNumAlignBits;
1474+ do
1475+ {
1476+ NORMALIZE_CHECK
1477+ range >>= 1;
1478+ code -= range & (((code - range) >> 31) - 1);
1479+ /* if (code >= range) code -= range; */
1480+ }
1481+ while (--numDirectBits != 0);
1482+ prob = probs + Align;
1483+ numDirectBits = kNumAlignBits;
1484+ }
1485+ {
1486+ unsigned i = 1;
1487+ do
1488+ {
1489+ GET_BIT_CHECK(prob + i, i);
1490+ }
1491+ while (--numDirectBits != 0);
1492+ }
1493+ }
1494+ }
1495+ }
1496+ }
1497+ NORMALIZE_CHECK;
1498+ return res;
1499+}
1500+
1501+
1502+static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
1503+{
1504+ p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
1505+ p->range = 0xFFFFFFFF;
1506+ p->needFlush = 0;
1507+}
1508+
1509+void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
1510+{
1511+ p->needFlush = 1;
1512+ p->remainLen = 0;
1513+ p->tempBufSize = 0;
1514+
1515+ if (initDic)
1516+ {
1517+ p->processedPos = 0;
1518+ p->checkDicSize = 0;
1519+ p->needInitState = 1;
1520+ }
1521+ if (initState)
1522+ p->needInitState = 1;
1523+}
1524+
1525+void LzmaDec_Init(CLzmaDec *p)
1526+{
1527+ p->dicPos = 0;
1528+ LzmaDec_InitDicAndState(p, True, True);
1529+}
1530+
1531+static void LzmaDec_InitStateReal(CLzmaDec *p)
1532+{
1533+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
1534+ UInt32 i;
1535+ CLzmaProb *probs = p->probs;
1536+ for (i = 0; i < numProbs; i++)
1537+ probs[i] = kBitModelTotal >> 1;
1538+ p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
1539+ p->state = 0;
1540+ p->needInitState = 0;
1541+}
1542+
1543+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
1544+ ELzmaFinishMode finishMode, ELzmaStatus *status)
1545+{
1546+ SizeT inSize = *srcLen;
1547+ (*srcLen) = 0;
1548+ LzmaDec_WriteRem(p, dicLimit);
1549+
1550+ *status = LZMA_STATUS_NOT_SPECIFIED;
1551+
1552+ while (p->remainLen != kMatchSpecLenStart)
1553+ {
1554+ int checkEndMarkNow;
1555+
1556+ if (p->needFlush != 0)
1557+ {
1558+ for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
1559+ p->tempBuf[p->tempBufSize++] = *src++;
1560+ if (p->tempBufSize < RC_INIT_SIZE)
1561+ {
1562+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
1563+ return SZ_OK;
1564+ }
1565+ if (p->tempBuf[0] != 0)
1566+ return SZ_ERROR_DATA;
1567+
1568+ LzmaDec_InitRc(p, p->tempBuf);
1569+ p->tempBufSize = 0;
1570+ }
1571+
1572+ checkEndMarkNow = 0;
1573+ if (p->dicPos >= dicLimit)
1574+ {
1575+ if (p->remainLen == 0 && p->code == 0)
1576+ {
1577+ *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
1578+ return SZ_OK;
1579+ }
1580+ if (finishMode == LZMA_FINISH_ANY)
1581+ {
1582+ *status = LZMA_STATUS_NOT_FINISHED;
1583+ return SZ_OK;
1584+ }
1585+ if (p->remainLen != 0)
1586+ {
1587+ *status = LZMA_STATUS_NOT_FINISHED;
1588+ return SZ_ERROR_DATA;
1589+ }
1590+ checkEndMarkNow = 1;
1591+ }
1592+
1593+ if (p->needInitState)
1594+ LzmaDec_InitStateReal(p);
1595+
1596+ if (p->tempBufSize == 0)
1597+ {
1598+ SizeT processed;
1599+ const Byte *bufLimit;
1600+ if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
1601+ {
1602+ int dummyRes = LzmaDec_TryDummy(p, src, inSize);
1603+ if (dummyRes == DUMMY_ERROR)
1604+ {
1605+ memcpy(p->tempBuf, src, inSize);
1606+ p->tempBufSize = (unsigned)inSize;
1607+ (*srcLen) += inSize;
1608+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
1609+ return SZ_OK;
1610+ }
1611+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
1612+ {
1613+ *status = LZMA_STATUS_NOT_FINISHED;
1614+ return SZ_ERROR_DATA;
1615+ }
1616+ bufLimit = src;
1617+ }
1618+ else
1619+ bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
1620+ p->buf = src;
1621+ if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
1622+ return SZ_ERROR_DATA;
1623+ processed = (SizeT)(p->buf - src);
1624+ (*srcLen) += processed;
1625+ src += processed;
1626+ inSize -= processed;
1627+ }
1628+ else
1629+ {
1630+ unsigned rem = p->tempBufSize, lookAhead = 0;
1631+ while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
1632+ p->tempBuf[rem++] = src[lookAhead++];
1633+ p->tempBufSize = rem;
1634+ if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
1635+ {
1636+ int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
1637+ if (dummyRes == DUMMY_ERROR)
1638+ {
1639+ (*srcLen) += lookAhead;
1640+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
1641+ return SZ_OK;
1642+ }
1643+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
1644+ {
1645+ *status = LZMA_STATUS_NOT_FINISHED;
1646+ return SZ_ERROR_DATA;
1647+ }
1648+ }
1649+ p->buf = p->tempBuf;
1650+ if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
1651+ return SZ_ERROR_DATA;
1652+ lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
1653+ (*srcLen) += lookAhead;
1654+ src += lookAhead;
1655+ inSize -= lookAhead;
1656+ p->tempBufSize = 0;
1657+ }
1658+ }
1659+ if (p->code == 0)
1660+ *status = LZMA_STATUS_FINISHED_WITH_MARK;
1661+ return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
1662+}
1663+
1664+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
1665+{
1666+ SizeT outSize = *destLen;
1667+ SizeT inSize = *srcLen;
1668+ *srcLen = *destLen = 0;
1669+ for (;;)
1670+ {
1671+ SizeT inSizeCur = inSize, outSizeCur, dicPos;
1672+ ELzmaFinishMode curFinishMode;
1673+ SRes res;
1674+ if (p->dicPos == p->dicBufSize)
1675+ p->dicPos = 0;
1676+ dicPos = p->dicPos;
1677+ if (outSize > p->dicBufSize - dicPos)
1678+ {
1679+ outSizeCur = p->dicBufSize;
1680+ curFinishMode = LZMA_FINISH_ANY;
1681+ }
1682+ else
1683+ {
1684+ outSizeCur = dicPos + outSize;
1685+ curFinishMode = finishMode;
1686+ }
1687+
1688+ res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
1689+ src += inSizeCur;
1690+ inSize -= inSizeCur;
1691+ *srcLen += inSizeCur;
1692+ outSizeCur = p->dicPos - dicPos;
1693+ memcpy(dest, p->dic + dicPos, outSizeCur);
1694+ dest += outSizeCur;
1695+ outSize -= outSizeCur;
1696+ *destLen += outSizeCur;
1697+ if (res != 0)
1698+ return res;
1699+ if (outSizeCur == 0 || outSize == 0)
1700+ return SZ_OK;
1701+ }
1702+}
1703+
1704+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
1705+{
1706+ alloc->Free(alloc, p->probs);
1707+ p->probs = 0;
1708+}
1709+
1710+static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
1711+{
1712+ alloc->Free(alloc, p->dic);
1713+ p->dic = 0;
1714+}
1715+
1716+void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
1717+{
1718+ LzmaDec_FreeProbs(p, alloc);
1719+ LzmaDec_FreeDict(p, alloc);
1720+}
1721+
1722+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
1723+{
1724+ UInt32 dicSize;
1725+ Byte d;
1726+
1727+ if (size < LZMA_PROPS_SIZE)
1728+ return SZ_ERROR_UNSUPPORTED;
1729+ else
1730+ dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
1731+
1732+ if (dicSize < LZMA_DIC_MIN)
1733+ dicSize = LZMA_DIC_MIN;
1734+ p->dicSize = dicSize;
1735+
1736+ d = data[0];
1737+ if (d >= (9 * 5 * 5))
1738+ return SZ_ERROR_UNSUPPORTED;
1739+
1740+ p->lc = d % 9;
1741+ d /= 9;
1742+ p->pb = d / 5;
1743+ p->lp = d % 5;
1744+
1745+ return SZ_OK;
1746+}
1747+
1748+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
1749+{
1750+ UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
1751+ if (p->probs == 0 || numProbs != p->numProbs)
1752+ {
1753+ LzmaDec_FreeProbs(p, alloc);
1754+ p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
1755+ p->numProbs = numProbs;
1756+ if (p->probs == 0)
1757+ return SZ_ERROR_MEM;
1758+ }
1759+ return SZ_OK;
1760+}
1761+
1762+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
1763+{
1764+ CLzmaProps propNew;
1765+ RINOK(LzmaProps_Decode(&propNew, props, propsSize));
1766+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
1767+ p->prop = propNew;
1768+ return SZ_OK;
1769+}
1770+
1771+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
1772+{
1773+ CLzmaProps propNew;
1774+ SizeT dicBufSize;
1775+ RINOK(LzmaProps_Decode(&propNew, props, propsSize));
1776+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
1777+ dicBufSize = propNew.dicSize;
1778+ if (p->dic == 0 || dicBufSize != p->dicBufSize)
1779+ {
1780+ LzmaDec_FreeDict(p, alloc);
1781+ p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
1782+ if (p->dic == 0)
1783+ {
1784+ LzmaDec_FreeProbs(p, alloc);
1785+ return SZ_ERROR_MEM;
1786+ }
1787+ }
1788+ p->dicBufSize = dicBufSize;
1789+ p->prop = propNew;
1790+ return SZ_OK;
1791+}
1792+
1793+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
1794+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
1795+ ELzmaStatus *status, ISzAlloc *alloc)
1796+{
1797+ CLzmaDec p;
1798+ SRes res;
1799+ SizeT inSize = *srcLen;
1800+ SizeT outSize = *destLen;
1801+ *srcLen = *destLen = 0;
1802+ if (inSize < RC_INIT_SIZE)
1803+ return SZ_ERROR_INPUT_EOF;
1804+
1805+ LzmaDec_Construct(&p);
1806+ res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
1807+ if (res != 0)
1808+ return res;
1809+ p.dic = dest;
1810+ p.dicBufSize = outSize;
1811+
1812+ LzmaDec_Init(&p);
1813+
1814+ *srcLen = inSize;
1815+ res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
1816+
1817+ if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
1818+ res = SZ_ERROR_INPUT_EOF;
1819+
1820+ (*destLen) = p.dicPos;
1821+ LzmaDec_FreeProbs(&p, alloc);
1822+ return res;
1823+}
1824
1825Property changes on: third_party/lzma_sdk/LzmaDec.c
1826___________________________________________________________________
1827Added: svn:eol-style
1828 + LF
1829
1830Index: third_party/lzma_sdk/README.ots
1831===================================================================
1832--- third_party/lzma_sdk/README.ots (revision 0)
1833+++ third_party/lzma_sdk/README.ots (revision 0)
1834@@ -0,0 +1,8 @@
1835+Name: LZMA SDK
1836+URL: http://www.7-zip.org/sdk.html
1837+Version: 9.20
1838+
1839+Description:
1840+The LZMA SDK provides the documentation, samples, header files, libraries, and tools you need to develop applications that use LZMA compression.
1841+
1842+This contains only the C code required to decompress LZMA.
1843Index: third_party/lzma_sdk/lzma_sdk.gyp
1844===================================================================
1845--- third_party/lzma_sdk/lzma_sdk.gyp (revision 0)
1846+++ third_party/lzma_sdk/lzma_sdk.gyp (revision 0)
1847@@ -0,0 +1,33 @@
1848+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
1849+# Use of this source code is governed by a BSD-style license that can be
1850+# found in the LICENSE file.
1851+
1852+{
1853+ 'targets': [
1854+ {
1855+ 'target_name': 'lzma_sdk',
1856+ 'type': 'static_library',
1857+ 'defines': [
1858+ '_7ZIP_ST',
1859+ '_LZMA_PROB32',
1860+ ],
1861+ 'sources': [
1862+ 'Alloc.c',
1863+ 'Alloc.h',
1864+ 'LzFind.c',
1865+ 'LzFind.h',
1866+ 'LzHash.h',
1867+ 'LzmaEnc.c',
1868+ 'LzmaEnc.h',
1869+ 'LzmaDec.c',
1870+ 'LzmaDec.h',
1871+ 'LzmaLib.c',
1872+ 'LzmaLib.h',
1873+ 'Types.h',
1874+ ],
1875+ 'include_dirs': [
1876+ '.',
1877+ ],
1878+ },
1879+ ],
1880+}
1881
1882Property changes on: third_party/lzma_sdk/lzma_sdk.gyp
1883___________________________________________________________________
1884Added: svn:eol-style
1885 + LF
1886
1887Index: third_party/lzma_sdk/LzmaDec.h
1888===================================================================
1889--- third_party/lzma_sdk/LzmaDec.h (revision 0)
1890+++ third_party/lzma_sdk/LzmaDec.h (revision 0)
1891@@ -0,0 +1,231 @@
1892+/* LzmaDec.h -- LZMA Decoder
1893+2009-02-07 : Igor Pavlov : Public domain */
1894+
1895+#ifndef __LZMA_DEC_H
1896+#define __LZMA_DEC_H
1897+
1898+#include "Types.h"
1899+
1900+#ifdef __cplusplus
1901+extern "C" {
1902+#endif
1903+
1904+/* #define _LZMA_PROB32 */
1905+/* _LZMA_PROB32 can increase the speed on some CPUs,
1906+ but memory usage for CLzmaDec::probs will be doubled in that case */
1907+
1908+#ifdef _LZMA_PROB32
1909+#define CLzmaProb UInt32
1910+#else
1911+#define CLzmaProb UInt16
1912+#endif
1913+
1914+
1915+/* ---------- LZMA Properties ---------- */
1916+
1917+#define LZMA_PROPS_SIZE 5
1918+
1919+typedef struct _CLzmaProps
1920+{
1921+ unsigned lc, lp, pb;
1922+ UInt32 dicSize;
1923+} CLzmaProps;
1924+
1925+/* LzmaProps_Decode - decodes properties
1926+Returns:
1927+ SZ_OK
1928+ SZ_ERROR_UNSUPPORTED - Unsupported properties
1929+*/
1930+
1931+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
1932+
1933+
1934+/* ---------- LZMA Decoder state ---------- */
1935+
1936+/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
1937+ Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
1938+
1939+#define LZMA_REQUIRED_INPUT_MAX 20
1940+
1941+typedef struct
1942+{
1943+ CLzmaProps prop;
1944+ CLzmaProb *probs;
1945+ Byte *dic;
1946+ const Byte *buf;
1947+ UInt32 range, code;
1948+ SizeT dicPos;
1949+ SizeT dicBufSize;
1950+ UInt32 processedPos;
1951+ UInt32 checkDicSize;
1952+ unsigned state;
1953+ UInt32 reps[4];
1954+ unsigned remainLen;
1955+ int needFlush;
1956+ int needInitState;
1957+ UInt32 numProbs;
1958+ unsigned tempBufSize;
1959+ Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
1960+} CLzmaDec;
1961+
1962+#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
1963+
1964+void LzmaDec_Init(CLzmaDec *p);
1965+
1966+/* There are two types of LZMA streams:
1967+ 0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
1968+ 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
1969+
1970+typedef enum
1971+{
1972+ LZMA_FINISH_ANY, /* finish at any point */
1973+ LZMA_FINISH_END /* block must be finished at the end */
1974+} ELzmaFinishMode;
1975+
1976+/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
1977+
1978+ You must use LZMA_FINISH_END, when you know that current output buffer
1979+ covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
1980+
1981+ If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
1982+ and output value of destLen will be less than output buffer size limit.
1983+ You can check status result also.
1984+
1985+ You can use multiple checks to test data integrity after full decompression:
1986+ 1) Check Result and "status" variable.
1987+ 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
1988+ 3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
1989+ You must use correct finish mode in that case. */
1990+
1991+typedef enum
1992+{
1993+ LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
1994+ LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
1995+ LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
1996+ LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
1997+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
1998+} ELzmaStatus;
1999+
2000+/* ELzmaStatus is used only as output value for function call */
2001+
2002+
2003+/* ---------- Interfaces ---------- */
2004+
2005+/* There are 3 levels of interfaces:
2006+ 1) Dictionary Interface
2007+ 2) Buffer Interface
2008+ 3) One Call Interface
2009+ You can select any of these interfaces, but don't mix functions from different
2010+ groups for same object. */
2011+
2012+
2013+/* There are two variants to allocate state for Dictionary Interface:
2014+ 1) LzmaDec_Allocate / LzmaDec_Free
2015+ 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
2016+ You can use variant 2, if you set dictionary buffer manually.
2017+ For Buffer Interface you must always use variant 1.
2018+
2019+LzmaDec_Allocate* can return:
2020+ SZ_OK
2021+ SZ_ERROR_MEM - Memory allocation error
2022+ SZ_ERROR_UNSUPPORTED - Unsupported properties
2023+*/
2024+
2025+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
2026+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
2027+
2028+SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
2029+void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
2030+
2031+/* ---------- Dictionary Interface ---------- */
2032+
2033+/* You can use it, if you want to eliminate the overhead for data copying from
2034+ dictionary to some other external buffer.
2035+ You must work with CLzmaDec variables directly in this interface.
2036+
2037+ STEPS:
2038+ LzmaDec_Constr()
2039+ LzmaDec_Allocate()
2040+ for (each new stream)
2041+ {
2042+ LzmaDec_Init()
2043+ while (it needs more decompression)
2044+ {
2045+ LzmaDec_DecodeToDic()
2046+ use data from CLzmaDec::dic and update CLzmaDec::dicPos
2047+ }
2048+ }
2049+ LzmaDec_Free()
2050+*/
2051+
2052+/* LzmaDec_DecodeToDic
2053+
2054+ The decoding to internal dictionary buffer (CLzmaDec::dic).
2055+ You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
2056+
2057+finishMode:
2058+ It has meaning only if the decoding reaches output limit (dicLimit).
2059+ LZMA_FINISH_ANY - Decode just dicLimit bytes.
2060+ LZMA_FINISH_END - Stream must be finished after dicLimit.
2061+
2062+Returns:
2063+ SZ_OK
2064+ status:
2065+ LZMA_STATUS_FINISHED_WITH_MARK
2066+ LZMA_STATUS_NOT_FINISHED
2067+ LZMA_STATUS_NEEDS_MORE_INPUT
2068+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
2069+ SZ_ERROR_DATA - Data error
2070+*/
2071+
2072+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
2073+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
2074+
2075+
2076+/* ---------- Buffer Interface ---------- */
2077+
2078+/* It's zlib-like interface.
2079+ See LzmaDec_DecodeToDic description for information about STEPS and return results,
2080+ but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
2081+ to work with CLzmaDec variables manually.
2082+
2083+finishMode:
2084+ It has meaning only if the decoding reaches output limit (*destLen).
2085+ LZMA_FINISH_ANY - Decode just destLen bytes.
2086+ LZMA_FINISH_END - Stream must be finished after (*destLen).
2087+*/
2088+
2089+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
2090+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
2091+
2092+
2093+/* ---------- One Call Interface ---------- */
2094+
2095+/* LzmaDecode
2096+
2097+finishMode:
2098+ It has meaning only if the decoding reaches output limit (*destLen).
2099+ LZMA_FINISH_ANY - Decode just destLen bytes.
2100+ LZMA_FINISH_END - Stream must be finished after (*destLen).
2101+
2102+Returns:
2103+ SZ_OK
2104+ status:
2105+ LZMA_STATUS_FINISHED_WITH_MARK
2106+ LZMA_STATUS_NOT_FINISHED
2107+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
2108+ SZ_ERROR_DATA - Data error
2109+ SZ_ERROR_MEM - Memory allocation error
2110+ SZ_ERROR_UNSUPPORTED - Unsupported properties
2111+ SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
2112+*/
2113+
2114+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
2115+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
2116+ ELzmaStatus *status, ISzAlloc *alloc);
2117+
2118+#ifdef __cplusplus
2119+}
2120+#endif
2121+
2122+#endif
2123
2124Property changes on: third_party/lzma_sdk/LzmaDec.h
2125___________________________________________________________________
2126Added: svn:eol-style
2127 + LF
2128
2129Index: third_party/lzma_sdk/LzFind.c
2130===================================================================
2131--- third_party/lzma_sdk/LzFind.c (revision 0)
2132+++ third_party/lzma_sdk/LzFind.c (revision 0)
2133@@ -0,0 +1,761 @@
2134+/* LzFind.c -- Match finder for LZ algorithms
2135+2009-04-22 : Igor Pavlov : Public domain */
2136+
2137+#include <string.h>
2138+
2139+#include "LzFind.h"
2140+#include "LzHash.h"
2141+
2142+#define kEmptyHashValue 0
2143+#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
2144+#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
2145+#define kNormalizeMask (~(kNormalizeStepMin - 1))
2146+#define kMaxHistorySize ((UInt32)3 << 30)
2147+
2148+#define kStartMaxLen 3
2149+
2150+static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
2151+{
2152+ if (!p->directInput)
2153+ {
2154+ alloc->Free(alloc, p->bufferBase);
2155+ p->bufferBase = 0;
2156+ }
2157+}
2158+
2159+/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
2160+
2161+static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
2162+{
2163+ UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
2164+ if (p->directInput)
2165+ {
2166+ p->blockSize = blockSize;
2167+ return 1;
2168+ }
2169+ if (p->bufferBase == 0 || p->blockSize != blockSize)
2170+ {
2171+ LzInWindow_Free(p, alloc);
2172+ p->blockSize = blockSize;
2173+ p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
2174+ }
2175+ return (p->bufferBase != 0);
2176+}
2177+
2178+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
2179+Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
2180+
2181+UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
2182+
2183+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
2184+{
2185+ p->posLimit -= subValue;
2186+ p->pos -= subValue;
2187+ p->streamPos -= subValue;
2188+}
2189+
2190+static void MatchFinder_ReadBlock(CMatchFinder *p)
2191+{
2192+ if (p->streamEndWasReached || p->result != SZ_OK)
2193+ return;
2194+ if (p->directInput)
2195+ {
2196+ UInt32 curSize = 0xFFFFFFFF - p->streamPos;
2197+ if (curSize > p->directInputRem)
2198+ curSize = (UInt32)p->directInputRem;
2199+ p->directInputRem -= curSize;
2200+ p->streamPos += curSize;
2201+ if (p->directInputRem == 0)
2202+ p->streamEndWasReached = 1;
2203+ return;
2204+ }
2205+ for (;;)
2206+ {
2207+ Byte *dest = p->buffer + (p->streamPos - p->pos);
2208+ size_t size = (p->bufferBase + p->blockSize - dest);
2209+ if (size == 0)
2210+ return;
2211+ p->result = p->stream->Read(p->stream, dest, &size);
2212+ if (p->result != SZ_OK)
2213+ return;
2214+ if (size == 0)
2215+ {
2216+ p->streamEndWasReached = 1;
2217+ return;
2218+ }
2219+ p->streamPos += (UInt32)size;
2220+ if (p->streamPos - p->pos > p->keepSizeAfter)
2221+ return;
2222+ }
2223+}
2224+
2225+void MatchFinder_MoveBlock(CMatchFinder *p)
2226+{
2227+ memmove(p->bufferBase,
2228+ p->buffer - p->keepSizeBefore,
2229+ (size_t)(p->streamPos - p->pos + p->keepSizeBefore));
2230+ p->buffer = p->bufferBase + p->keepSizeBefore;
2231+}
2232+
2233+int MatchFinder_NeedMove(CMatchFinder *p)
2234+{
2235+ if (p->directInput)
2236+ return 0;
2237+ /* if (p->streamEndWasReached) return 0; */
2238+ return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
2239+}
2240+
2241+void MatchFinder_ReadIfRequired(CMatchFinder *p)
2242+{
2243+ if (p->streamEndWasReached)
2244+ return;
2245+ if (p->keepSizeAfter >= p->streamPos - p->pos)
2246+ MatchFinder_ReadBlock(p);
2247+}
2248+
2249+static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
2250+{
2251+ if (MatchFinder_NeedMove(p))
2252+ MatchFinder_MoveBlock(p);
2253+ MatchFinder_ReadBlock(p);
2254+}
2255+
2256+static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
2257+{
2258+ p->cutValue = 32;
2259+ p->btMode = 1;
2260+ p->numHashBytes = 4;
2261+ p->bigHash = 0;
2262+}
2263+
2264+#define kCrcPoly 0xEDB88320
2265+
2266+void MatchFinder_Construct(CMatchFinder *p)
2267+{
2268+ UInt32 i;
2269+ p->bufferBase = 0;
2270+ p->directInput = 0;
2271+ p->hash = 0;
2272+ MatchFinder_SetDefaultSettings(p);
2273+
2274+ for (i = 0; i < 256; i++)
2275+ {
2276+ UInt32 r = i;
2277+ int j;
2278+ for (j = 0; j < 8; j++)
2279+ r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
2280+ p->crc[i] = r;
2281+ }
2282+}
2283+
2284+static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
2285+{
2286+ alloc->Free(alloc, p->hash);
2287+ p->hash = 0;
2288+}
2289+
2290+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
2291+{
2292+ MatchFinder_FreeThisClassMemory(p, alloc);
2293+ LzInWindow_Free(p, alloc);
2294+}
2295+
2296+static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
2297+{
2298+ size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
2299+ if (sizeInBytes / sizeof(CLzRef) != num)
2300+ return 0;
2301+ return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
2302+}
2303+
2304+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
2305+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
2306+ ISzAlloc *alloc)
2307+{
2308+ UInt32 sizeReserv;
2309+ if (historySize > kMaxHistorySize)
2310+ {
2311+ MatchFinder_Free(p, alloc);
2312+ return 0;
2313+ }
2314+ sizeReserv = historySize >> 1;
2315+ if (historySize > ((UInt32)2 << 30))
2316+ sizeReserv = historySize >> 2;
2317+ sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
2318+
2319+ p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
2320+ p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
2321+ /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
2322+ if (LzInWindow_Create(p, sizeReserv, alloc))
2323+ {
2324+ UInt32 newCyclicBufferSize = historySize + 1;
2325+ UInt32 hs;
2326+ p->matchMaxLen = matchMaxLen;
2327+ {
2328+ p->fixedHashSize = 0;
2329+ if (p->numHashBytes == 2)
2330+ hs = (1 << 16) - 1;
2331+ else
2332+ {
2333+ hs = historySize - 1;
2334+ hs |= (hs >> 1);
2335+ hs |= (hs >> 2);
2336+ hs |= (hs >> 4);
2337+ hs |= (hs >> 8);
2338+ hs >>= 1;
2339+ hs |= 0xFFFF; /* don't change it! It's required for Deflate */
2340+ if (hs > (1 << 24))
2341+ {
2342+ if (p->numHashBytes == 3)
2343+ hs = (1 << 24) - 1;
2344+ else
2345+ hs >>= 1;
2346+ }
2347+ }
2348+ p->hashMask = hs;
2349+ hs++;
2350+ if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;
2351+ if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;
2352+ if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;
2353+ hs += p->fixedHashSize;
2354+ }
2355+
2356+ {
2357+ UInt32 prevSize = p->hashSizeSum + p->numSons;
2358+ UInt32 newSize;
2359+ p->historySize = historySize;
2360+ p->hashSizeSum = hs;
2361+ p->cyclicBufferSize = newCyclicBufferSize;
2362+ p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
2363+ newSize = p->hashSizeSum + p->numSons;
2364+ if (p->hash != 0 && prevSize == newSize)
2365+ return 1;
2366+ MatchFinder_FreeThisClassMemory(p, alloc);
2367+ p->hash = AllocRefs(newSize, alloc);
2368+ if (p->hash != 0)
2369+ {
2370+ p->son = p->hash + p->hashSizeSum;
2371+ return 1;
2372+ }
2373+ }
2374+ }
2375+ MatchFinder_Free(p, alloc);
2376+ return 0;
2377+}
2378+
2379+static void MatchFinder_SetLimits(CMatchFinder *p)
2380+{
2381+ UInt32 limit = kMaxValForNormalize - p->pos;
2382+ UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
2383+ if (limit2 < limit)
2384+ limit = limit2;
2385+ limit2 = p->streamPos - p->pos;
2386+ if (limit2 <= p->keepSizeAfter)
2387+ {
2388+ if (limit2 > 0)
2389+ limit2 = 1;
2390+ }
2391+ else
2392+ limit2 -= p->keepSizeAfter;
2393+ if (limit2 < limit)
2394+ limit = limit2;
2395+ {
2396+ UInt32 lenLimit = p->streamPos - p->pos;
2397+ if (lenLimit > p->matchMaxLen)
2398+ lenLimit = p->matchMaxLen;
2399+ p->lenLimit = lenLimit;
2400+ }
2401+ p->posLimit = p->pos + limit;
2402+}
2403+
2404+void MatchFinder_Init(CMatchFinder *p)
2405+{
2406+ UInt32 i;
2407+ for (i = 0; i < p->hashSizeSum; i++)
2408+ p->hash[i] = kEmptyHashValue;
2409+ p->cyclicBufferPos = 0;
2410+ p->buffer = p->bufferBase;
2411+ p->pos = p->streamPos = p->cyclicBufferSize;
2412+ p->result = SZ_OK;
2413+ p->streamEndWasReached = 0;
2414+ MatchFinder_ReadBlock(p);
2415+ MatchFinder_SetLimits(p);
2416+}
2417+
2418+static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
2419+{
2420+ return (p->pos - p->historySize - 1) & kNormalizeMask;
2421+}
2422+
2423+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
2424+{
2425+ UInt32 i;
2426+ for (i = 0; i < numItems; i++)
2427+ {
2428+ UInt32 value = items[i];
2429+ if (value <= subValue)
2430+ value = kEmptyHashValue;
2431+ else
2432+ value -= subValue;
2433+ items[i] = value;
2434+ }
2435+}
2436+
2437+static void MatchFinder_Normalize(CMatchFinder *p)
2438+{
2439+ UInt32 subValue = MatchFinder_GetSubValue(p);
2440+ MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
2441+ MatchFinder_ReduceOffsets(p, subValue);
2442+}
2443+
2444+static void MatchFinder_CheckLimits(CMatchFinder *p)
2445+{
2446+ if (p->pos == kMaxValForNormalize)
2447+ MatchFinder_Normalize(p);
2448+ if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
2449+ MatchFinder_CheckAndMoveAndRead(p);
2450+ if (p->cyclicBufferPos == p->cyclicBufferSize)
2451+ p->cyclicBufferPos = 0;
2452+ MatchFinder_SetLimits(p);
2453+}
2454+
2455+static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
2456+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
2457+ UInt32 *distances, UInt32 maxLen)
2458+{
2459+ son[_cyclicBufferPos] = curMatch;
2460+ for (;;)
2461+ {
2462+ UInt32 delta = pos - curMatch;
2463+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
2464+ return distances;
2465+ {
2466+ const Byte *pb = cur - delta;
2467+ curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
2468+ if (pb[maxLen] == cur[maxLen] && *pb == *cur)
2469+ {
2470+ UInt32 len = 0;
2471+ while (++len != lenLimit)
2472+ if (pb[len] != cur[len])
2473+ break;
2474+ if (maxLen < len)
2475+ {
2476+ *distances++ = maxLen = len;
2477+ *distances++ = delta - 1;
2478+ if (len == lenLimit)
2479+ return distances;
2480+ }
2481+ }
2482+ }
2483+ }
2484+}
2485+
2486+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
2487+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
2488+ UInt32 *distances, UInt32 maxLen)
2489+{
2490+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
2491+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
2492+ UInt32 len0 = 0, len1 = 0;
2493+ for (;;)
2494+ {
2495+ UInt32 delta = pos - curMatch;
2496+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
2497+ {
2498+ *ptr0 = *ptr1 = kEmptyHashValue;
2499+ return distances;
2500+ }
2501+ {
2502+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
2503+ const Byte *pb = cur - delta;
2504+ UInt32 len = (len0 < len1 ? len0 : len1);
2505+ if (pb[len] == cur[len])
2506+ {
2507+ if (++len != lenLimit && pb[len] == cur[len])
2508+ while (++len != lenLimit)
2509+ if (pb[len] != cur[len])
2510+ break;
2511+ if (maxLen < len)
2512+ {
2513+ *distances++ = maxLen = len;
2514+ *distances++ = delta - 1;
2515+ if (len == lenLimit)
2516+ {
2517+ *ptr1 = pair[0];
2518+ *ptr0 = pair[1];
2519+ return distances;
2520+ }
2521+ }
2522+ }
2523+ if (pb[len] < cur[len])
2524+ {
2525+ *ptr1 = curMatch;
2526+ ptr1 = pair + 1;
2527+ curMatch = *ptr1;
2528+ len1 = len;
2529+ }
2530+ else
2531+ {
2532+ *ptr0 = curMatch;
2533+ ptr0 = pair;
2534+ curMatch = *ptr0;
2535+ len0 = len;
2536+ }
2537+ }
2538+ }
2539+}
2540+
2541+static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
2542+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
2543+{
2544+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
2545+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
2546+ UInt32 len0 = 0, len1 = 0;
2547+ for (;;)
2548+ {
2549+ UInt32 delta = pos - curMatch;
2550+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
2551+ {
2552+ *ptr0 = *ptr1 = kEmptyHashValue;
2553+ return;
2554+ }
2555+ {
2556+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
2557+ const Byte *pb = cur - delta;
2558+ UInt32 len = (len0 < len1 ? len0 : len1);
2559+ if (pb[len] == cur[len])
2560+ {
2561+ while (++len != lenLimit)
2562+ if (pb[len] != cur[len])
2563+ break;
2564+ {
2565+ if (len == lenLimit)
2566+ {
2567+ *ptr1 = pair[0];
2568+ *ptr0 = pair[1];
2569+ return;
2570+ }
2571+ }
2572+ }
2573+ if (pb[len] < cur[len])
2574+ {
2575+ *ptr1 = curMatch;
2576+ ptr1 = pair + 1;
2577+ curMatch = *ptr1;
2578+ len1 = len;
2579+ }
2580+ else
2581+ {
2582+ *ptr0 = curMatch;
2583+ ptr0 = pair;
2584+ curMatch = *ptr0;
2585+ len0 = len;
2586+ }
2587+ }
2588+ }
2589+}
2590+
2591+#define MOVE_POS \
2592+ ++p->cyclicBufferPos; \
2593+ p->buffer++; \
2594+ if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
2595+
2596+#define MOVE_POS_RET MOVE_POS return offset;
2597+
2598+static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
2599+
2600+#define GET_MATCHES_HEADER2(minLen, ret_op) \
2601+ UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \
2602+ lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
2603+ cur = p->buffer;
2604+
2605+#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
2606+#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue)
2607+
2608+#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
2609+
2610+#define GET_MATCHES_FOOTER(offset, maxLen) \
2611+ offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \
2612+ distances + offset, maxLen) - distances); MOVE_POS_RET;
2613+
2614+#define SKIP_FOOTER \
2615+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
2616+
2617+static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
2618+{
2619+ UInt32 offset;
2620+ GET_MATCHES_HEADER(2)
2621+ HASH2_CALC;
2622+ curMatch = p->hash[hashValue];
2623+ p->hash[hashValue] = p->pos;
2624+ offset = 0;
2625+ GET_MATCHES_FOOTER(offset, 1)
2626+}
2627+
2628+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
2629+{
2630+ UInt32 offset;
2631+ GET_MATCHES_HEADER(3)
2632+ HASH_ZIP_CALC;
2633+ curMatch = p->hash[hashValue];
2634+ p->hash[hashValue] = p->pos;
2635+ offset = 0;
2636+ GET_MATCHES_FOOTER(offset, 2)
2637+}
2638+
2639+static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
2640+{
2641+ UInt32 hash2Value, delta2, maxLen, offset;
2642+ GET_MATCHES_HEADER(3)
2643+
2644+ HASH3_CALC;
2645+
2646+ delta2 = p->pos - p->hash[hash2Value];
2647+ curMatch = p->hash[kFix3HashSize + hashValue];
2648+
2649+ p->hash[hash2Value] =
2650+ p->hash[kFix3HashSize + hashValue] = p->pos;
2651+
2652+
2653+ maxLen = 2;
2654+ offset = 0;
2655+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
2656+ {
2657+ for (; maxLen != lenLimit; maxLen++)
2658+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
2659+ break;
2660+ distances[0] = maxLen;
2661+ distances[1] = delta2 - 1;
2662+ offset = 2;
2663+ if (maxLen == lenLimit)
2664+ {
2665+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
2666+ MOVE_POS_RET;
2667+ }
2668+ }
2669+ GET_MATCHES_FOOTER(offset, maxLen)
2670+}
2671+
2672+static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
2673+{
2674+ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
2675+ GET_MATCHES_HEADER(4)
2676+
2677+ HASH4_CALC;
2678+
2679+ delta2 = p->pos - p->hash[ hash2Value];
2680+ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
2681+ curMatch = p->hash[kFix4HashSize + hashValue];
2682+
2683+ p->hash[ hash2Value] =
2684+ p->hash[kFix3HashSize + hash3Value] =
2685+ p->hash[kFix4HashSize + hashValue] = p->pos;
2686+
2687+ maxLen = 1;
2688+ offset = 0;
2689+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
2690+ {
2691+ distances[0] = maxLen = 2;
2692+ distances[1] = delta2 - 1;
2693+ offset = 2;
2694+ }
2695+ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
2696+ {
2697+ maxLen = 3;
2698+ distances[offset + 1] = delta3 - 1;
2699+ offset += 2;
2700+ delta2 = delta3;
2701+ }
2702+ if (offset != 0)
2703+ {
2704+ for (; maxLen != lenLimit; maxLen++)
2705+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
2706+ break;
2707+ distances[offset - 2] = maxLen;
2708+ if (maxLen == lenLimit)
2709+ {
2710+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
2711+ MOVE_POS_RET;
2712+ }
2713+ }
2714+ if (maxLen < 3)
2715+ maxLen = 3;
2716+ GET_MATCHES_FOOTER(offset, maxLen)
2717+}
2718+
2719+static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
2720+{
2721+ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
2722+ GET_MATCHES_HEADER(4)
2723+
2724+ HASH4_CALC;
2725+
2726+ delta2 = p->pos - p->hash[ hash2Value];
2727+ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
2728+ curMatch = p->hash[kFix4HashSize + hashValue];
2729+
2730+ p->hash[ hash2Value] =
2731+ p->hash[kFix3HashSize + hash3Value] =
2732+ p->hash[kFix4HashSize + hashValue] = p->pos;
2733+
2734+ maxLen = 1;
2735+ offset = 0;
2736+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
2737+ {
2738+ distances[0] = maxLen = 2;
2739+ distances[1] = delta2 - 1;
2740+ offset = 2;
2741+ }
2742+ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
2743+ {
2744+ maxLen = 3;
2745+ distances[offset + 1] = delta3 - 1;
2746+ offset += 2;
2747+ delta2 = delta3;
2748+ }
2749+ if (offset != 0)
2750+ {
2751+ for (; maxLen != lenLimit; maxLen++)
2752+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
2753+ break;
2754+ distances[offset - 2] = maxLen;
2755+ if (maxLen == lenLimit)
2756+ {
2757+ p->son[p->cyclicBufferPos] = curMatch;
2758+ MOVE_POS_RET;
2759+ }
2760+ }
2761+ if (maxLen < 3)
2762+ maxLen = 3;
2763+ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
2764+ distances + offset, maxLen) - (distances));
2765+ MOVE_POS_RET
2766+}
2767+
2768+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
2769+{
2770+ UInt32 offset;
2771+ GET_MATCHES_HEADER(3)
2772+ HASH_ZIP_CALC;
2773+ curMatch = p->hash[hashValue];
2774+ p->hash[hashValue] = p->pos;
2775+ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
2776+ distances, 2) - (distances));
2777+ MOVE_POS_RET
2778+}
2779+
2780+static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
2781+{
2782+ do
2783+ {
2784+ SKIP_HEADER(2)
2785+ HASH2_CALC;
2786+ curMatch = p->hash[hashValue];
2787+ p->hash[hashValue] = p->pos;
2788+ SKIP_FOOTER
2789+ }
2790+ while (--num != 0);
2791+}
2792+
2793+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
2794+{
2795+ do
2796+ {
2797+ SKIP_HEADER(3)
2798+ HASH_ZIP_CALC;
2799+ curMatch = p->hash[hashValue];
2800+ p->hash[hashValue] = p->pos;
2801+ SKIP_FOOTER
2802+ }
2803+ while (--num != 0);
2804+}
2805+
2806+static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
2807+{
2808+ do
2809+ {
2810+ UInt32 hash2Value;
2811+ SKIP_HEADER(3)
2812+ HASH3_CALC;
2813+ curMatch = p->hash[kFix3HashSize + hashValue];
2814+ p->hash[hash2Value] =
2815+ p->hash[kFix3HashSize + hashValue] = p->pos;
2816+ SKIP_FOOTER
2817+ }
2818+ while (--num != 0);
2819+}
2820+
2821+static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
2822+{
2823+ do
2824+ {
2825+ UInt32 hash2Value, hash3Value;
2826+ SKIP_HEADER(4)
2827+ HASH4_CALC;
2828+ curMatch = p->hash[kFix4HashSize + hashValue];
2829+ p->hash[ hash2Value] =
2830+ p->hash[kFix3HashSize + hash3Value] = p->pos;
2831+ p->hash[kFix4HashSize + hashValue] = p->pos;
2832+ SKIP_FOOTER
2833+ }
2834+ while (--num != 0);
2835+}
2836+
2837+static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
2838+{
2839+ do
2840+ {
2841+ UInt32 hash2Value, hash3Value;
2842+ SKIP_HEADER(4)
2843+ HASH4_CALC;
2844+ curMatch = p->hash[kFix4HashSize + hashValue];
2845+ p->hash[ hash2Value] =
2846+ p->hash[kFix3HashSize + hash3Value] =
2847+ p->hash[kFix4HashSize + hashValue] = p->pos;
2848+ p->son[p->cyclicBufferPos] = curMatch;
2849+ MOVE_POS
2850+ }
2851+ while (--num != 0);
2852+}
2853+
2854+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
2855+{
2856+ do
2857+ {
2858+ SKIP_HEADER(3)
2859+ HASH_ZIP_CALC;
2860+ curMatch = p->hash[hashValue];
2861+ p->hash[hashValue] = p->pos;
2862+ p->son[p->cyclicBufferPos] = curMatch;
2863+ MOVE_POS
2864+ }
2865+ while (--num != 0);
2866+}
2867+
2868+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
2869+{
2870+ vTable->Init = (Mf_Init_Func)MatchFinder_Init;
2871+ vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
2872+ vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
2873+ vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
2874+ if (!p->btMode)
2875+ {
2876+ vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
2877+ vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
2878+ }
2879+ else if (p->numHashBytes == 2)
2880+ {
2881+ vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
2882+ vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;
2883+ }
2884+ else if (p->numHashBytes == 3)
2885+ {
2886+ vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
2887+ vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
2888+ }
2889+ else
2890+ {
2891+ vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
2892+ vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
2893+ }
2894+}
2895
2896Property changes on: third_party/lzma_sdk/LzFind.c
2897___________________________________________________________________
2898Added: svn:eol-style
2899 + LF
2900
2901Index: third_party/lzma_sdk/LzmaEnc.c
2902===================================================================
2903--- third_party/lzma_sdk/LzmaEnc.c (revision 0)
2904+++ third_party/lzma_sdk/LzmaEnc.c (revision 0)
2905@@ -0,0 +1,2268 @@
2906+/* LzmaEnc.c -- LZMA Encoder
2907+2010-04-16 : Igor Pavlov : Public domain */
2908+
2909+#include <string.h>
2910+
2911+/* #define SHOW_STAT */
2912+/* #define SHOW_STAT2 */
2913+
2914+#if defined(SHOW_STAT) || defined(SHOW_STAT2)
2915+#include <stdio.h>
2916+#endif
2917+
2918+#include "LzmaEnc.h"
2919+
2920+#include "LzFind.h"
2921+#ifndef _7ZIP_ST
2922+#include "LzFindMt.h"
2923+#endif
2924+
2925+#ifdef SHOW_STAT
2926+static int ttt = 0;
2927+#endif
2928+
2929+#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
2930+
2931+#define kBlockSize (9 << 10)
2932+#define kUnpackBlockSize (1 << 18)
2933+#define kMatchArraySize (1 << 21)
2934+#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX)
2935+
2936+#define kNumMaxDirectBits (31)
2937+
2938+#define kNumTopBits 24
2939+#define kTopValue ((UInt32)1 << kNumTopBits)
2940+
2941+#define kNumBitModelTotalBits 11
2942+#define kBitModelTotal (1 << kNumBitModelTotalBits)
2943+#define kNumMoveBits 5
2944+#define kProbInitValue (kBitModelTotal >> 1)
2945+
2946+#define kNumMoveReducingBits 4
2947+#define kNumBitPriceShiftBits 4
2948+#define kBitPrice (1 << kNumBitPriceShiftBits)
2949+
2950+void LzmaEncProps_Init(CLzmaEncProps *p)
2951+{
2952+ p->level = 5;
2953+ p->dictSize = p->mc = 0;
2954+ p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;
2955+ p->writeEndMark = 0;
2956+}
2957+
2958+void LzmaEncProps_Normalize(CLzmaEncProps *p)
2959+{
2960+ int level = p->level;
2961+ if (level < 0) level = 5;
2962+ p->level = level;
2963+ if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));
2964+ if (p->lc < 0) p->lc = 3;
2965+ if (p->lp < 0) p->lp = 0;
2966+ if (p->pb < 0) p->pb = 2;
2967+ if (p->algo < 0) p->algo = (level < 5 ? 0 : 1);
2968+ if (p->fb < 0) p->fb = (level < 7 ? 32 : 64);
2969+ if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
2970+ if (p->numHashBytes < 0) p->numHashBytes = 4;
2971+ if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1);
2972+ if (p->numThreads < 0)
2973+ p->numThreads =
2974+ #ifndef _7ZIP_ST
2975+ ((p->btMode && p->algo) ? 2 : 1);
2976+ #else
2977+ 1;
2978+ #endif
2979+}
2980+
2981+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
2982+{
2983+ CLzmaEncProps props = *props2;
2984+ LzmaEncProps_Normalize(&props);
2985+ return props.dictSize;
2986+}
2987+
2988+/* #define LZMA_LOG_BSR */
2989+/* Define it for Intel's CPU */
2990+
2991+
2992+#ifdef LZMA_LOG_BSR
2993+
2994+#define kDicLogSizeMaxCompress 30
2995+
2996+#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }
2997+
2998+UInt32 GetPosSlot1(UInt32 pos)
2999+{
3000+ UInt32 res;
3001+ BSR2_RET(pos, res);
3002+ return res;
3003+}
3004+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
3005+#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); }
3006+
3007+#else
3008+
3009+#define kNumLogBits (9 + (int)sizeof(size_t) / 2)
3010+#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
3011+
3012+void LzmaEnc_FastPosInit(Byte *g_FastPos)
3013+{
3014+ int c = 2, slotFast;
3015+ g_FastPos[0] = 0;
3016+ g_FastPos[1] = 1;
3017+
3018+ for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++)
3019+ {
3020+ UInt32 k = (1 << ((slotFast >> 1) - 1));
3021+ UInt32 j;
3022+ for (j = 0; j < k; j++, c++)
3023+ g_FastPos[c] = (Byte)slotFast;
3024+ }
3025+}
3026+
3027+#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
3028+ (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
3029+ res = p->g_FastPos[pos >> i] + (i * 2); }
3030+/*
3031+#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
3032+ p->g_FastPos[pos >> 6] + 12 : \
3033+ p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; }
3034+*/
3035+
3036+#define GetPosSlot1(pos) p->g_FastPos[pos]
3037+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
3038+#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); }
3039+
3040+#endif
3041+
3042+
3043+#define LZMA_NUM_REPS 4
3044+
3045+typedef unsigned CState;
3046+
3047+typedef struct
3048+{
3049+ UInt32 price;
3050+
3051+ CState state;
3052+ int prev1IsChar;
3053+ int prev2;
3054+
3055+ UInt32 posPrev2;
3056+ UInt32 backPrev2;
3057+
3058+ UInt32 posPrev;
3059+ UInt32 backPrev;
3060+ UInt32 backs[LZMA_NUM_REPS];
3061+} COptimal;
3062+
3063+#define kNumOpts (1 << 12)
3064+
3065+#define kNumLenToPosStates 4
3066+#define kNumPosSlotBits 6
3067+#define kDicLogSizeMin 0
3068+#define kDicLogSizeMax 32
3069+#define kDistTableSizeMax (kDicLogSizeMax * 2)
3070+
3071+
3072+#define kNumAlignBits 4
3073+#define kAlignTableSize (1 << kNumAlignBits)
3074+#define kAlignMask (kAlignTableSize - 1)
3075+
3076+#define kStartPosModelIndex 4
3077+#define kEndPosModelIndex 14
3078+#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex)
3079+
3080+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
3081+
3082+#ifdef _LZMA_PROB32
3083+#define CLzmaProb UInt32
3084+#else
3085+#define CLzmaProb UInt16
3086+#endif
3087+
3088+#define LZMA_PB_MAX 4
3089+#define LZMA_LC_MAX 8
3090+#define LZMA_LP_MAX 4
3091+
3092+#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX)
3093+
3094+
3095+#define kLenNumLowBits 3
3096+#define kLenNumLowSymbols (1 << kLenNumLowBits)
3097+#define kLenNumMidBits 3
3098+#define kLenNumMidSymbols (1 << kLenNumMidBits)
3099+#define kLenNumHighBits 8
3100+#define kLenNumHighSymbols (1 << kLenNumHighBits)
3101+
3102+#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
3103+
3104+#define LZMA_MATCH_LEN_MIN 2
3105+#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1)
3106+
3107+#define kNumStates 12
3108+
3109+typedef struct
3110+{
3111+ CLzmaProb choice;
3112+ CLzmaProb choice2;
3113+ CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits];
3114+ CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits];
3115+ CLzmaProb high[kLenNumHighSymbols];
3116+} CLenEnc;
3117+
3118+typedef struct
3119+{
3120+ CLenEnc p;
3121+ UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
3122+ UInt32 tableSize;
3123+ UInt32 counters[LZMA_NUM_PB_STATES_MAX];
3124+} CLenPriceEnc;
3125+
3126+typedef struct
3127+{
3128+ UInt32 range;
3129+ Byte cache;
3130+ UInt64 low;
3131+ UInt64 cacheSize;
3132+ Byte *buf;
3133+ Byte *bufLim;
3134+ Byte *bufBase;
3135+ ISeqOutStream *outStream;
3136+ UInt64 processed;
3137+ SRes res;
3138+} CRangeEnc;
3139+
3140+typedef struct
3141+{
3142+ CLzmaProb *litProbs;
3143+
3144+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
3145+ CLzmaProb isRep[kNumStates];
3146+ CLzmaProb isRepG0[kNumStates];
3147+ CLzmaProb isRepG1[kNumStates];
3148+ CLzmaProb isRepG2[kNumStates];
3149+ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
3150+
3151+ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
3152+ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
3153+ CLzmaProb posAlignEncoder[1 << kNumAlignBits];
3154+
3155+ CLenPriceEnc lenEnc;
3156+ CLenPriceEnc repLenEnc;
3157+
3158+ UInt32 reps[LZMA_NUM_REPS];
3159+ UInt32 state;
3160+} CSaveState;
3161+
3162+typedef struct
3163+{
3164+ IMatchFinder matchFinder;
3165+ void *matchFinderObj;
3166+
3167+ #ifndef _7ZIP_ST
3168+ Bool mtMode;
3169+ CMatchFinderMt matchFinderMt;
3170+ #endif
3171+
3172+ CMatchFinder matchFinderBase;
3173+
3174+ #ifndef _7ZIP_ST
3175+ Byte pad[128];
3176+ #endif
3177+
3178+ UInt32 optimumEndIndex;
3179+ UInt32 optimumCurrentIndex;
3180+
3181+ UInt32 longestMatchLength;
3182+ UInt32 numPairs;
3183+ UInt32 numAvail;
3184+ COptimal opt[kNumOpts];
3185+
3186+ #ifndef LZMA_LOG_BSR
3187+ Byte g_FastPos[1 << kNumLogBits];
3188+ #endif
3189+
3190+ UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
3191+ UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];
3192+ UInt32 numFastBytes;
3193+ UInt32 additionalOffset;
3194+ UInt32 reps[LZMA_NUM_REPS];
3195+ UInt32 state;
3196+
3197+ UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
3198+ UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
3199+ UInt32 alignPrices[kAlignTableSize];
3200+ UInt32 alignPriceCount;
3201+
3202+ UInt32 distTableSize;
3203+
3204+ unsigned lc, lp, pb;
3205+ unsigned lpMask, pbMask;
3206+
3207+ CLzmaProb *litProbs;
3208+
3209+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
3210+ CLzmaProb isRep[kNumStates];
3211+ CLzmaProb isRepG0[kNumStates];
3212+ CLzmaProb isRepG1[kNumStates];
3213+ CLzmaProb isRepG2[kNumStates];
3214+ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
3215+
3216+ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
3217+ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
3218+ CLzmaProb posAlignEncoder[1 << kNumAlignBits];
3219+
3220+ CLenPriceEnc lenEnc;
3221+ CLenPriceEnc repLenEnc;
3222+
3223+ unsigned lclp;
3224+
3225+ Bool fastMode;
3226+
3227+ CRangeEnc rc;
3228+
3229+ Bool writeEndMark;
3230+ UInt64 nowPos64;
3231+ UInt32 matchPriceCount;
3232+ Bool finished;
3233+ Bool multiThread;
3234+
3235+ SRes result;
3236+ UInt32 dictSize;
3237+ UInt32 matchFinderCycles;
3238+
3239+ int needInit;
3240+
3241+ CSaveState saveState;
3242+} CLzmaEnc;
3243+
3244+void LzmaEnc_SaveState(CLzmaEncHandle pp)
3245+{
3246+ CLzmaEnc *p = (CLzmaEnc *)pp;
3247+ CSaveState *dest = &p->saveState;
3248+ int i;
3249+ dest->lenEnc = p->lenEnc;
3250+ dest->repLenEnc = p->repLenEnc;
3251+ dest->state = p->state;
3252+
3253+ for (i = 0; i < kNumStates; i++)
3254+ {
3255+ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
3256+ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
3257+ }
3258+ for (i = 0; i < kNumLenToPosStates; i++)
3259+ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
3260+ memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
3261+ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
3262+ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
3263+ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
3264+ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
3265+ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
3266+ memcpy(dest->reps, p->reps, sizeof(p->reps));
3267+ memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb));
3268+}
3269+
3270+void LzmaEnc_RestoreState(CLzmaEncHandle pp)
3271+{
3272+ CLzmaEnc *dest = (CLzmaEnc *)pp;
3273+ const CSaveState *p = &dest->saveState;
3274+ int i;
3275+ dest->lenEnc = p->lenEnc;
3276+ dest->repLenEnc = p->repLenEnc;
3277+ dest->state = p->state;
3278+
3279+ for (i = 0; i < kNumStates; i++)
3280+ {
3281+ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
3282+ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
3283+ }
3284+ for (i = 0; i < kNumLenToPosStates; i++)
3285+ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
3286+ memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
3287+ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
3288+ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
3289+ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
3290+ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
3291+ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
3292+ memcpy(dest->reps, p->reps, sizeof(p->reps));
3293+ memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb));
3294+}
3295+
3296+SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
3297+{
3298+ CLzmaEnc *p = (CLzmaEnc *)pp;
3299+ CLzmaEncProps props = *props2;
3300+ LzmaEncProps_Normalize(&props);
3301+
3302+ if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||
3303+ props.dictSize > ((UInt32)1 << kDicLogSizeMaxCompress) || props.dictSize > ((UInt32)1 << 30))
3304+ return SZ_ERROR_PARAM;
3305+ p->dictSize = props.dictSize;
3306+ p->matchFinderCycles = props.mc;
3307+ {
3308+ unsigned fb = props.fb;
3309+ if (fb < 5)
3310+ fb = 5;
3311+ if (fb > LZMA_MATCH_LEN_MAX)
3312+ fb = LZMA_MATCH_LEN_MAX;
3313+ p->numFastBytes = fb;
3314+ }
3315+ p->lc = props.lc;
3316+ p->lp = props.lp;
3317+ p->pb = props.pb;
3318+ p->fastMode = (props.algo == 0);
3319+ p->matchFinderBase.btMode = props.btMode;
3320+ {
3321+ UInt32 numHashBytes = 4;
3322+ if (props.btMode)
3323+ {
3324+ if (props.numHashBytes < 2)
3325+ numHashBytes = 2;
3326+ else if (props.numHashBytes < 4)
3327+ numHashBytes = props.numHashBytes;
3328+ }
3329+ p->matchFinderBase.numHashBytes = numHashBytes;
3330+ }
3331+
3332+ p->matchFinderBase.cutValue = props.mc;
3333+
3334+ p->writeEndMark = props.writeEndMark;
3335+
3336+ #ifndef _7ZIP_ST
3337+ /*
3338+ if (newMultiThread != _multiThread)
3339+ {
3340+ ReleaseMatchFinder();
3341+ _multiThread = newMultiThread;
3342+ }
3343+ */
3344+ p->multiThread = (props.numThreads > 1);
3345+ #endif
3346+
3347+ return SZ_OK;
3348+}
3349+
3350+static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
3351+static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
3352+static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
3353+static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
3354+
3355+#define IsCharState(s) ((s) < 7)
3356+
3357+#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1)
3358+
3359+#define kInfinityPrice (1 << 30)
3360+
3361+static void RangeEnc_Construct(CRangeEnc *p)
3362+{
3363+ p->outStream = 0;
3364+ p->bufBase = 0;
3365+}
3366+
3367+#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
3368+
3369+#define RC_BUF_SIZE (1 << 16)
3370+static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
3371+{
3372+ if (p->bufBase == 0)
3373+ {
3374+ p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
3375+ if (p->bufBase == 0)
3376+ return 0;
3377+ p->bufLim = p->bufBase + RC_BUF_SIZE;
3378+ }
3379+ return 1;
3380+}
3381+
3382+static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc)
3383+{
3384+ alloc->Free(alloc, p->bufBase);
3385+ p->bufBase = 0;
3386+}
3387+
3388+static void RangeEnc_Init(CRangeEnc *p)
3389+{
3390+ /* Stream.Init(); */
3391+ p->low = 0;
3392+ p->range = 0xFFFFFFFF;
3393+ p->cacheSize = 1;
3394+ p->cache = 0;
3395+
3396+ p->buf = p->bufBase;
3397+
3398+ p->processed = 0;
3399+ p->res = SZ_OK;
3400+}
3401+
3402+static void RangeEnc_FlushStream(CRangeEnc *p)
3403+{
3404+ size_t num;
3405+ if (p->res != SZ_OK)
3406+ return;
3407+ num = p->buf - p->bufBase;
3408+ if (num != p->outStream->Write(p->outStream, p->bufBase, num))
3409+ p->res = SZ_ERROR_WRITE;
3410+ p->processed += num;
3411+ p->buf = p->bufBase;
3412+}
3413+
3414+static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)
3415+{
3416+ if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0)
3417+ {
3418+ Byte temp = p->cache;
3419+ do
3420+ {
3421+ Byte *buf = p->buf;
3422+ *buf++ = (Byte)(temp + (Byte)(p->low >> 32));
3423+ p->buf = buf;
3424+ if (buf == p->bufLim)
3425+ RangeEnc_FlushStream(p);
3426+ temp = 0xFF;
3427+ }
3428+ while (--p->cacheSize != 0);
3429+ p->cache = (Byte)((UInt32)p->low >> 24);
3430+ }
3431+ p->cacheSize++;
3432+ p->low = (UInt32)p->low << 8;
3433+}
3434+
3435+static void RangeEnc_FlushData(CRangeEnc *p)
3436+{
3437+ int i;
3438+ for (i = 0; i < 5; i++)
3439+ RangeEnc_ShiftLow(p);
3440+}
3441+
3442+static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits)
3443+{
3444+ do
3445+ {
3446+ p->range >>= 1;
3447+ p->low += p->range & (0 - ((value >> --numBits) & 1));
3448+ if (p->range < kTopValue)
3449+ {
3450+ p->range <<= 8;
3451+ RangeEnc_ShiftLow(p);
3452+ }
3453+ }
3454+ while (numBits != 0);
3455+}
3456+
3457+static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol)
3458+{
3459+ UInt32 ttt = *prob;
3460+ UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt;
3461+ if (symbol == 0)
3462+ {
3463+ p->range = newBound;
3464+ ttt += (kBitModelTotal - ttt) >> kNumMoveBits;
3465+ }
3466+ else
3467+ {
3468+ p->low += newBound;
3469+ p->range -= newBound;
3470+ ttt -= ttt >> kNumMoveBits;
3471+ }
3472+ *prob = (CLzmaProb)ttt;
3473+ if (p->range < kTopValue)
3474+ {
3475+ p->range <<= 8;
3476+ RangeEnc_ShiftLow(p);
3477+ }
3478+}
3479+
3480+static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol)
3481+{
3482+ symbol |= 0x100;
3483+ do
3484+ {
3485+ RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1);
3486+ symbol <<= 1;
3487+ }
3488+ while (symbol < 0x10000);
3489+}
3490+
3491+static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte)
3492+{
3493+ UInt32 offs = 0x100;
3494+ symbol |= 0x100;
3495+ do
3496+ {
3497+ matchByte <<= 1;
3498+ RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1);
3499+ symbol <<= 1;
3500+ offs &= ~(matchByte ^ symbol);
3501+ }
3502+ while (symbol < 0x10000);
3503+}
3504+
3505+void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
3506+{
3507+ UInt32 i;
3508+ for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
3509+ {
3510+ const int kCyclesBits = kNumBitPriceShiftBits;
3511+ UInt32 w = i;
3512+ UInt32 bitCount = 0;
3513+ int j;
3514+ for (j = 0; j < kCyclesBits; j++)
3515+ {
3516+ w = w * w;
3517+ bitCount <<= 1;
3518+ while (w >= ((UInt32)1 << 16))
3519+ {
3520+ w >>= 1;
3521+ bitCount++;
3522+ }
3523+ }
3524+ ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount);
3525+ }
3526+}
3527+
3528+
3529+#define GET_PRICE(prob, symbol) \
3530+ p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
3531+
3532+#define GET_PRICEa(prob, symbol) \
3533+ ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
3534+
3535+#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits]
3536+#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
3537+
3538+#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
3539+#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
3540+
3541+static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices)
3542+{
3543+ UInt32 price = 0;
3544+ symbol |= 0x100;
3545+ do
3546+ {
3547+ price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1);
3548+ symbol <<= 1;
3549+ }
3550+ while (symbol < 0x10000);
3551+ return price;
3552+}
3553+
3554+static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices)
3555+{
3556+ UInt32 price = 0;
3557+ UInt32 offs = 0x100;
3558+ symbol |= 0x100;
3559+ do
3560+ {
3561+ matchByte <<= 1;
3562+ price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1);
3563+ symbol <<= 1;
3564+ offs &= ~(matchByte ^ symbol);
3565+ }
3566+ while (symbol < 0x10000);
3567+ return price;
3568+}
3569+
3570+
3571+static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
3572+{
3573+ UInt32 m = 1;
3574+ int i;
3575+ for (i = numBitLevels; i != 0;)
3576+ {
3577+ UInt32 bit;
3578+ i--;
3579+ bit = (symbol >> i) & 1;
3580+ RangeEnc_EncodeBit(rc, probs + m, bit);
3581+ m = (m << 1) | bit;
3582+ }
3583+}
3584+
3585+static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
3586+{
3587+ UInt32 m = 1;
3588+ int i;
3589+ for (i = 0; i < numBitLevels; i++)
3590+ {
3591+ UInt32 bit = symbol & 1;
3592+ RangeEnc_EncodeBit(rc, probs + m, bit);
3593+ m = (m << 1) | bit;
3594+ symbol >>= 1;
3595+ }
3596+}
3597+
3598+static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
3599+{
3600+ UInt32 price = 0;
3601+ symbol |= (1 << numBitLevels);
3602+ while (symbol != 1)
3603+ {
3604+ price += GET_PRICEa(probs[symbol >> 1], symbol & 1);
3605+ symbol >>= 1;
3606+ }
3607+ return price;
3608+}
3609+
3610+static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
3611+{
3612+ UInt32 price = 0;
3613+ UInt32 m = 1;
3614+ int i;
3615+ for (i = numBitLevels; i != 0; i--)
3616+ {
3617+ UInt32 bit = symbol & 1;
3618+ symbol >>= 1;
3619+ price += GET_PRICEa(probs[m], bit);
3620+ m = (m << 1) | bit;
3621+ }
3622+ return price;
3623+}
3624+
3625+
3626+static void LenEnc_Init(CLenEnc *p)
3627+{
3628+ unsigned i;
3629+ p->choice = p->choice2 = kProbInitValue;
3630+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++)
3631+ p->low[i] = kProbInitValue;
3632+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++)
3633+ p->mid[i] = kProbInitValue;
3634+ for (i = 0; i < kLenNumHighSymbols; i++)
3635+ p->high[i] = kProbInitValue;
3636+}
3637+
3638+static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState)
3639+{
3640+ if (symbol < kLenNumLowSymbols)
3641+ {
3642+ RangeEnc_EncodeBit(rc, &p->choice, 0);
3643+ RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol);
3644+ }
3645+ else
3646+ {
3647+ RangeEnc_EncodeBit(rc, &p->choice, 1);
3648+ if (symbol < kLenNumLowSymbols + kLenNumMidSymbols)
3649+ {
3650+ RangeEnc_EncodeBit(rc, &p->choice2, 0);
3651+ RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols);
3652+ }
3653+ else
3654+ {
3655+ RangeEnc_EncodeBit(rc, &p->choice2, 1);
3656+ RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols);
3657+ }
3658+ }
3659+}
3660+
3661+static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices)
3662+{
3663+ UInt32 a0 = GET_PRICE_0a(p->choice);
3664+ UInt32 a1 = GET_PRICE_1a(p->choice);
3665+ UInt32 b0 = a1 + GET_PRICE_0a(p->choice2);
3666+ UInt32 b1 = a1 + GET_PRICE_1a(p->choice2);
3667+ UInt32 i = 0;
3668+ for (i = 0; i < kLenNumLowSymbols; i++)
3669+ {
3670+ if (i >= numSymbols)
3671+ return;
3672+ prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices);
3673+ }
3674+ for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++)
3675+ {
3676+ if (i >= numSymbols)
3677+ return;
3678+ prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices);
3679+ }
3680+ for (; i < numSymbols; i++)
3681+ prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices);
3682+}
3683+
3684+static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices)
3685+{
3686+ LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices);
3687+ p->counters[posState] = p->tableSize;
3688+}
3689+
3690+static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices)
3691+{
3692+ UInt32 posState;
3693+ for (posState = 0; posState < numPosStates; posState++)
3694+ LenPriceEnc_UpdateTable(p, posState, ProbPrices);
3695+}
3696+
3697+static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices)
3698+{
3699+ LenEnc_Encode(&p->p, rc, symbol, posState);
3700+ if (updatePrice)
3701+ if (--p->counters[posState] == 0)
3702+ LenPriceEnc_UpdateTable(p, posState, ProbPrices);
3703+}
3704+
3705+
3706+
3707+
3708+static void MovePos(CLzmaEnc *p, UInt32 num)
3709+{
3710+ #ifdef SHOW_STAT
3711+ ttt += num;
3712+ printf("\n MovePos %d", num);
3713+ #endif
3714+ if (num != 0)
3715+ {
3716+ p->additionalOffset += num;
3717+ p->matchFinder.Skip(p->matchFinderObj, num);
3718+ }
3719+}
3720+
3721+static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
3722+{
3723+ UInt32 lenRes = 0, numPairs;
3724+ p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
3725+ numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
3726+ #ifdef SHOW_STAT
3727+ printf("\n i = %d numPairs = %d ", ttt, numPairs / 2);
3728+ ttt++;
3729+ {
3730+ UInt32 i;
3731+ for (i = 0; i < numPairs; i += 2)
3732+ printf("%2d %6d | ", p->matches[i], p->matches[i + 1]);
3733+ }
3734+ #endif
3735+ if (numPairs > 0)
3736+ {
3737+ lenRes = p->matches[numPairs - 2];
3738+ if (lenRes == p->numFastBytes)
3739+ {
3740+ const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
3741+ UInt32 distance = p->matches[numPairs - 1] + 1;
3742+ UInt32 numAvail = p->numAvail;
3743+ if (numAvail > LZMA_MATCH_LEN_MAX)
3744+ numAvail = LZMA_MATCH_LEN_MAX;
3745+ {
3746+ const Byte *pby2 = pby - distance;
3747+ for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++);
3748+ }
3749+ }
3750+ }
3751+ p->additionalOffset++;
3752+ *numDistancePairsRes = numPairs;
3753+ return lenRes;
3754+}
3755+
3756+
3757+#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False;
3758+#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False;
3759+#define IsShortRep(p) ((p)->backPrev == 0)
3760+
3761+static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState)
3762+{
3763+ return
3764+ GET_PRICE_0(p->isRepG0[state]) +
3765+ GET_PRICE_0(p->isRep0Long[state][posState]);
3766+}
3767+
3768+static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState)
3769+{
3770+ UInt32 price;
3771+ if (repIndex == 0)
3772+ {
3773+ price = GET_PRICE_0(p->isRepG0[state]);
3774+ price += GET_PRICE_1(p->isRep0Long[state][posState]);
3775+ }
3776+ else
3777+ {
3778+ price = GET_PRICE_1(p->isRepG0[state]);
3779+ if (repIndex == 1)
3780+ price += GET_PRICE_0(p->isRepG1[state]);
3781+ else
3782+ {
3783+ price += GET_PRICE_1(p->isRepG1[state]);
3784+ price += GET_PRICE(p->isRepG2[state], repIndex - 2);
3785+ }
3786+ }
3787+ return price;
3788+}
3789+
3790+static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState)
3791+{
3792+ return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] +
3793+ GetPureRepPrice(p, repIndex, state, posState);
3794+}
3795+
3796+static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
3797+{
3798+ UInt32 posMem = p->opt[cur].posPrev;
3799+ UInt32 backMem = p->opt[cur].backPrev;
3800+ p->optimumEndIndex = cur;
3801+ do
3802+ {
3803+ if (p->opt[cur].prev1IsChar)
3804+ {
3805+ MakeAsChar(&p->opt[posMem])
3806+ p->opt[posMem].posPrev = posMem - 1;
3807+ if (p->opt[cur].prev2)
3808+ {
3809+ p->opt[posMem - 1].prev1IsChar = False;
3810+ p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2;
3811+ p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2;
3812+ }
3813+ }
3814+ {
3815+ UInt32 posPrev = posMem;
3816+ UInt32 backCur = backMem;
3817+
3818+ backMem = p->opt[posPrev].backPrev;
3819+ posMem = p->opt[posPrev].posPrev;
3820+
3821+ p->opt[posPrev].backPrev = backCur;
3822+ p->opt[posPrev].posPrev = cur;
3823+ cur = posPrev;
3824+ }
3825+ }
3826+ while (cur != 0);
3827+ *backRes = p->opt[0].backPrev;
3828+ p->optimumCurrentIndex = p->opt[0].posPrev;
3829+ return p->optimumCurrentIndex;
3830+}
3831+
3832+#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300)
3833+
3834+static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
3835+{
3836+ UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur;
3837+ UInt32 matchPrice, repMatchPrice, normalMatchPrice;
3838+ UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS];
3839+ UInt32 *matches;
3840+ const Byte *data;
3841+ Byte curByte, matchByte;
3842+ if (p->optimumEndIndex != p->optimumCurrentIndex)
3843+ {
3844+ const COptimal *opt = &p->opt[p->optimumCurrentIndex];
3845+ UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex;
3846+ *backRes = opt->backPrev;
3847+ p->optimumCurrentIndex = opt->posPrev;
3848+ return lenRes;
3849+ }
3850+ p->optimumCurrentIndex = p->optimumEndIndex = 0;
3851+
3852+ if (p->additionalOffset == 0)
3853+ mainLen = ReadMatchDistances(p, &numPairs);
3854+ else
3855+ {
3856+ mainLen = p->longestMatchLength;
3857+ numPairs = p->numPairs;
3858+ }
3859+
3860+ numAvail = p->numAvail;
3861+ if (numAvail < 2)
3862+ {
3863+ *backRes = (UInt32)(-1);
3864+ return 1;
3865+ }
3866+ if (numAvail > LZMA_MATCH_LEN_MAX)
3867+ numAvail = LZMA_MATCH_LEN_MAX;
3868+
3869+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
3870+ repMaxIndex = 0;
3871+ for (i = 0; i < LZMA_NUM_REPS; i++)
3872+ {
3873+ UInt32 lenTest;
3874+ const Byte *data2;
3875+ reps[i] = p->reps[i];
3876+ data2 = data - (reps[i] + 1);
3877+ if (data[0] != data2[0] || data[1] != data2[1])
3878+ {
3879+ repLens[i] = 0;
3880+ continue;
3881+ }
3882+ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
3883+ repLens[i] = lenTest;
3884+ if (lenTest > repLens[repMaxIndex])
3885+ repMaxIndex = i;
3886+ }
3887+ if (repLens[repMaxIndex] >= p->numFastBytes)
3888+ {
3889+ UInt32 lenRes;
3890+ *backRes = repMaxIndex;
3891+ lenRes = repLens[repMaxIndex];
3892+ MovePos(p, lenRes - 1);
3893+ return lenRes;
3894+ }
3895+
3896+ matches = p->matches;
3897+ if (mainLen >= p->numFastBytes)
3898+ {
3899+ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
3900+ MovePos(p, mainLen - 1);
3901+ return mainLen;
3902+ }
3903+ curByte = *data;
3904+ matchByte = *(data - (reps[0] + 1));
3905+
3906+ if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2)
3907+ {
3908+ *backRes = (UInt32)-1;
3909+ return 1;
3910+ }
3911+
3912+ p->opt[0].state = (CState)p->state;
3913+
3914+ posState = (position & p->pbMask);
3915+
3916+ {
3917+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
3918+ p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) +
3919+ (!IsCharState(p->state) ?
3920+ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
3921+ LitEnc_GetPrice(probs, curByte, p->ProbPrices));
3922+ }
3923+
3924+ MakeAsChar(&p->opt[1]);
3925+
3926+ matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]);
3927+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]);
3928+
3929+ if (matchByte == curByte)
3930+ {
3931+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState);
3932+ if (shortRepPrice < p->opt[1].price)
3933+ {
3934+ p->opt[1].price = shortRepPrice;
3935+ MakeAsShortRep(&p->opt[1]);
3936+ }
3937+ }
3938+ lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]);
3939+
3940+ if (lenEnd < 2)
3941+ {
3942+ *backRes = p->opt[1].backPrev;
3943+ return 1;
3944+ }
3945+
3946+ p->opt[1].posPrev = 0;
3947+ for (i = 0; i < LZMA_NUM_REPS; i++)
3948+ p->opt[0].backs[i] = reps[i];
3949+
3950+ len = lenEnd;
3951+ do
3952+ p->opt[len--].price = kInfinityPrice;
3953+ while (len >= 2);
3954+
3955+ for (i = 0; i < LZMA_NUM_REPS; i++)
3956+ {
3957+ UInt32 repLen = repLens[i];
3958+ UInt32 price;
3959+ if (repLen < 2)
3960+ continue;
3961+ price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState);
3962+ do
3963+ {
3964+ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2];
3965+ COptimal *opt = &p->opt[repLen];
3966+ if (curAndLenPrice < opt->price)
3967+ {
3968+ opt->price = curAndLenPrice;
3969+ opt->posPrev = 0;
3970+ opt->backPrev = i;
3971+ opt->prev1IsChar = False;
3972+ }
3973+ }
3974+ while (--repLen >= 2);
3975+ }
3976+
3977+ normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]);
3978+
3979+ len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
3980+ if (len <= mainLen)
3981+ {
3982+ UInt32 offs = 0;
3983+ while (len > matches[offs])
3984+ offs += 2;
3985+ for (; ; len++)
3986+ {
3987+ COptimal *opt;
3988+ UInt32 distance = matches[offs + 1];
3989+
3990+ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN];
3991+ UInt32 lenToPosState = GetLenToPosState(len);
3992+ if (distance < kNumFullDistances)
3993+ curAndLenPrice += p->distancesPrices[lenToPosState][distance];
3994+ else
3995+ {
3996+ UInt32 slot;
3997+ GetPosSlot2(distance, slot);
3998+ curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot];
3999+ }
4000+ opt = &p->opt[len];
4001+ if (curAndLenPrice < opt->price)
4002+ {
4003+ opt->price = curAndLenPrice;
4004+ opt->posPrev = 0;
4005+ opt->backPrev = distance + LZMA_NUM_REPS;
4006+ opt->prev1IsChar = False;
4007+ }
4008+ if (len == matches[offs])
4009+ {
4010+ offs += 2;
4011+ if (offs == numPairs)
4012+ break;
4013+ }
4014+ }
4015+ }
4016+
4017+ cur = 0;
4018+
4019+ #ifdef SHOW_STAT2
4020+ if (position >= 0)
4021+ {
4022+ unsigned i;
4023+ printf("\n pos = %4X", position);
4024+ for (i = cur; i <= lenEnd; i++)
4025+ printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price);
4026+ }
4027+ #endif
4028+
4029+ for (;;)
4030+ {
4031+ UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen;
4032+ UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice;
4033+ Bool nextIsChar;
4034+ Byte curByte, matchByte;
4035+ const Byte *data;
4036+ COptimal *curOpt;
4037+ COptimal *nextOpt;
4038+
4039+ cur++;
4040+ if (cur == lenEnd)
4041+ return Backward(p, backRes, cur);
4042+
4043+ newLen = ReadMatchDistances(p, &numPairs);
4044+ if (newLen >= p->numFastBytes)
4045+ {
4046+ p->numPairs = numPairs;
4047+ p->longestMatchLength = newLen;
4048+ return Backward(p, backRes, cur);
4049+ }
4050+ position++;
4051+ curOpt = &p->opt[cur];
4052+ posPrev = curOpt->posPrev;
4053+ if (curOpt->prev1IsChar)
4054+ {
4055+ posPrev--;
4056+ if (curOpt->prev2)
4057+ {
4058+ state = p->opt[curOpt->posPrev2].state;
4059+ if (curOpt->backPrev2 < LZMA_NUM_REPS)
4060+ state = kRepNextStates[state];
4061+ else
4062+ state = kMatchNextStates[state];
4063+ }
4064+ else
4065+ state = p->opt[posPrev].state;
4066+ state = kLiteralNextStates[state];
4067+ }
4068+ else
4069+ state = p->opt[posPrev].state;
4070+ if (posPrev == cur - 1)
4071+ {
4072+ if (IsShortRep(curOpt))
4073+ state = kShortRepNextStates[state];
4074+ else
4075+ state = kLiteralNextStates[state];
4076+ }
4077+ else
4078+ {
4079+ UInt32 pos;
4080+ const COptimal *prevOpt;
4081+ if (curOpt->prev1IsChar && curOpt->prev2)
4082+ {
4083+ posPrev = curOpt->posPrev2;
4084+ pos = curOpt->backPrev2;
4085+ state = kRepNextStates[state];
4086+ }
4087+ else
4088+ {
4089+ pos = curOpt->backPrev;
4090+ if (pos < LZMA_NUM_REPS)
4091+ state = kRepNextStates[state];
4092+ else
4093+ state = kMatchNextStates[state];
4094+ }
4095+ prevOpt = &p->opt[posPrev];
4096+ if (pos < LZMA_NUM_REPS)
4097+ {
4098+ UInt32 i;
4099+ reps[0] = prevOpt->backs[pos];
4100+ for (i = 1; i <= pos; i++)
4101+ reps[i] = prevOpt->backs[i - 1];
4102+ for (; i < LZMA_NUM_REPS; i++)
4103+ reps[i] = prevOpt->backs[i];
4104+ }
4105+ else
4106+ {
4107+ UInt32 i;
4108+ reps[0] = (pos - LZMA_NUM_REPS);
4109+ for (i = 1; i < LZMA_NUM_REPS; i++)
4110+ reps[i] = prevOpt->backs[i - 1];
4111+ }
4112+ }
4113+ curOpt->state = (CState)state;
4114+
4115+ curOpt->backs[0] = reps[0];
4116+ curOpt->backs[1] = reps[1];
4117+ curOpt->backs[2] = reps[2];
4118+ curOpt->backs[3] = reps[3];
4119+
4120+ curPrice = curOpt->price;
4121+ nextIsChar = False;
4122+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
4123+ curByte = *data;
4124+ matchByte = *(data - (reps[0] + 1));
4125+
4126+ posState = (position & p->pbMask);
4127+
4128+ curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]);
4129+ {
4130+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
4131+ curAnd1Price +=
4132+ (!IsCharState(state) ?
4133+ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
4134+ LitEnc_GetPrice(probs, curByte, p->ProbPrices));
4135+ }
4136+
4137+ nextOpt = &p->opt[cur + 1];
4138+
4139+ if (curAnd1Price < nextOpt->price)
4140+ {
4141+ nextOpt->price = curAnd1Price;
4142+ nextOpt->posPrev = cur;
4143+ MakeAsChar(nextOpt);
4144+ nextIsChar = True;
4145+ }
4146+
4147+ matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]);
4148+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]);
4149+
4150+ if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0))
4151+ {
4152+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState);
4153+ if (shortRepPrice <= nextOpt->price)
4154+ {
4155+ nextOpt->price = shortRepPrice;
4156+ nextOpt->posPrev = cur;
4157+ MakeAsShortRep(nextOpt);
4158+ nextIsChar = True;
4159+ }
4160+ }
4161+ numAvailFull = p->numAvail;
4162+ {
4163+ UInt32 temp = kNumOpts - 1 - cur;
4164+ if (temp < numAvailFull)
4165+ numAvailFull = temp;
4166+ }
4167+
4168+ if (numAvailFull < 2)
4169+ continue;
4170+ numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes);
4171+
4172+ if (!nextIsChar && matchByte != curByte) /* speed optimization */
4173+ {
4174+ /* try Literal + rep0 */
4175+ UInt32 temp;
4176+ UInt32 lenTest2;
4177+ const Byte *data2 = data - (reps[0] + 1);
4178+ UInt32 limit = p->numFastBytes + 1;
4179+ if (limit > numAvailFull)
4180+ limit = numAvailFull;
4181+
4182+ for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++);
4183+ lenTest2 = temp - 1;
4184+ if (lenTest2 >= 2)
4185+ {
4186+ UInt32 state2 = kLiteralNextStates[state];
4187+ UInt32 posStateNext = (position + 1) & p->pbMask;
4188+ UInt32 nextRepMatchPrice = curAnd1Price +
4189+ GET_PRICE_1(p->isMatch[state2][posStateNext]) +
4190+ GET_PRICE_1(p->isRep[state2]);
4191+ /* for (; lenTest2 >= 2; lenTest2--) */
4192+ {
4193+ UInt32 curAndLenPrice;
4194+ COptimal *opt;
4195+ UInt32 offset = cur + 1 + lenTest2;
4196+ while (lenEnd < offset)
4197+ p->opt[++lenEnd].price = kInfinityPrice;
4198+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
4199+ opt = &p->opt[offset];
4200+ if (curAndLenPrice < opt->price)
4201+ {
4202+ opt->price = curAndLenPrice;
4203+ opt->posPrev = cur + 1;
4204+ opt->backPrev = 0;
4205+ opt->prev1IsChar = True;
4206+ opt->prev2 = False;
4207+ }
4208+ }
4209+ }
4210+ }
4211+
4212+ startLen = 2; /* speed optimization */
4213+ {
4214+ UInt32 repIndex;
4215+ for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++)
4216+ {
4217+ UInt32 lenTest;
4218+ UInt32 lenTestTemp;
4219+ UInt32 price;
4220+ const Byte *data2 = data - (reps[repIndex] + 1);
4221+ if (data[0] != data2[0] || data[1] != data2[1])
4222+ continue;
4223+ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
4224+ while (lenEnd < cur + lenTest)
4225+ p->opt[++lenEnd].price = kInfinityPrice;
4226+ lenTestTemp = lenTest;
4227+ price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState);
4228+ do
4229+ {
4230+ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2];
4231+ COptimal *opt = &p->opt[cur + lenTest];
4232+ if (curAndLenPrice < opt->price)
4233+ {
4234+ opt->price = curAndLenPrice;
4235+ opt->posPrev = cur;
4236+ opt->backPrev = repIndex;
4237+ opt->prev1IsChar = False;
4238+ }
4239+ }
4240+ while (--lenTest >= 2);
4241+ lenTest = lenTestTemp;
4242+
4243+ if (repIndex == 0)
4244+ startLen = lenTest + 1;
4245+
4246+ /* if (_maxMode) */
4247+ {
4248+ UInt32 lenTest2 = lenTest + 1;
4249+ UInt32 limit = lenTest2 + p->numFastBytes;
4250+ UInt32 nextRepMatchPrice;
4251+ if (limit > numAvailFull)
4252+ limit = numAvailFull;
4253+ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
4254+ lenTest2 -= lenTest + 1;
4255+ if (lenTest2 >= 2)
4256+ {
4257+ UInt32 state2 = kRepNextStates[state];
4258+ UInt32 posStateNext = (position + lenTest) & p->pbMask;
4259+ UInt32 curAndLenCharPrice =
4260+ price + p->repLenEnc.prices[posState][lenTest - 2] +
4261+ GET_PRICE_0(p->isMatch[state2][posStateNext]) +
4262+ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
4263+ data[lenTest], data2[lenTest], p->ProbPrices);
4264+ state2 = kLiteralNextStates[state2];
4265+ posStateNext = (position + lenTest + 1) & p->pbMask;
4266+ nextRepMatchPrice = curAndLenCharPrice +
4267+ GET_PRICE_1(p->isMatch[state2][posStateNext]) +
4268+ GET_PRICE_1(p->isRep[state2]);
4269+
4270+ /* for (; lenTest2 >= 2; lenTest2--) */
4271+ {
4272+ UInt32 curAndLenPrice;
4273+ COptimal *opt;
4274+ UInt32 offset = cur + lenTest + 1 + lenTest2;
4275+ while (lenEnd < offset)
4276+ p->opt[++lenEnd].price = kInfinityPrice;
4277+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
4278+ opt = &p->opt[offset];
4279+ if (curAndLenPrice < opt->price)
4280+ {
4281+ opt->price = curAndLenPrice;
4282+ opt->posPrev = cur + lenTest + 1;
4283+ opt->backPrev = 0;
4284+ opt->prev1IsChar = True;
4285+ opt->prev2 = True;
4286+ opt->posPrev2 = cur;
4287+ opt->backPrev2 = repIndex;
4288+ }
4289+ }
4290+ }
4291+ }
4292+ }
4293+ }
4294+ /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */
4295+ if (newLen > numAvail)
4296+ {
4297+ newLen = numAvail;
4298+ for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2);
4299+ matches[numPairs] = newLen;
4300+ numPairs += 2;
4301+ }
4302+ if (newLen >= startLen)
4303+ {
4304+ UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]);
4305+ UInt32 offs, curBack, posSlot;
4306+ UInt32 lenTest;
4307+ while (lenEnd < cur + newLen)
4308+ p->opt[++lenEnd].price = kInfinityPrice;
4309+
4310+ offs = 0;
4311+ while (startLen > matches[offs])
4312+ offs += 2;
4313+ curBack = matches[offs + 1];
4314+ GetPosSlot2(curBack, posSlot);
4315+ for (lenTest = /*2*/ startLen; ; lenTest++)
4316+ {
4317+ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN];
4318+ UInt32 lenToPosState = GetLenToPosState(lenTest);
4319+ COptimal *opt;
4320+ if (curBack < kNumFullDistances)
4321+ curAndLenPrice += p->distancesPrices[lenToPosState][curBack];
4322+ else
4323+ curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask];
4324+
4325+ opt = &p->opt[cur + lenTest];
4326+ if (curAndLenPrice < opt->price)
4327+ {
4328+ opt->price = curAndLenPrice;
4329+ opt->posPrev = cur;
4330+ opt->backPrev = curBack + LZMA_NUM_REPS;
4331+ opt->prev1IsChar = False;
4332+ }
4333+
4334+ if (/*_maxMode && */lenTest == matches[offs])
4335+ {
4336+ /* Try Match + Literal + Rep0 */
4337+ const Byte *data2 = data - (curBack + 1);
4338+ UInt32 lenTest2 = lenTest + 1;
4339+ UInt32 limit = lenTest2 + p->numFastBytes;
4340+ UInt32 nextRepMatchPrice;
4341+ if (limit > numAvailFull)
4342+ limit = numAvailFull;
4343+ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
4344+ lenTest2 -= lenTest + 1;
4345+ if (lenTest2 >= 2)
4346+ {
4347+ UInt32 state2 = kMatchNextStates[state];
4348+ UInt32 posStateNext = (position + lenTest) & p->pbMask;
4349+ UInt32 curAndLenCharPrice = curAndLenPrice +
4350+ GET_PRICE_0(p->isMatch[state2][posStateNext]) +
4351+ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
4352+ data[lenTest], data2[lenTest], p->ProbPrices);
4353+ state2 = kLiteralNextStates[state2];
4354+ posStateNext = (posStateNext + 1) & p->pbMask;
4355+ nextRepMatchPrice = curAndLenCharPrice +
4356+ GET_PRICE_1(p->isMatch[state2][posStateNext]) +
4357+ GET_PRICE_1(p->isRep[state2]);
4358+
4359+ /* for (; lenTest2 >= 2; lenTest2--) */
4360+ {
4361+ UInt32 offset = cur + lenTest + 1 + lenTest2;
4362+ UInt32 curAndLenPrice;
4363+ COptimal *opt;
4364+ while (lenEnd < offset)
4365+ p->opt[++lenEnd].price = kInfinityPrice;
4366+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
4367+ opt = &p->opt[offset];
4368+ if (curAndLenPrice < opt->price)
4369+ {
4370+ opt->price = curAndLenPrice;
4371+ opt->posPrev = cur + lenTest + 1;
4372+ opt->backPrev = 0;
4373+ opt->prev1IsChar = True;
4374+ opt->prev2 = True;
4375+ opt->posPrev2 = cur;
4376+ opt->backPrev2 = curBack + LZMA_NUM_REPS;
4377+ }
4378+ }
4379+ }
4380+ offs += 2;
4381+ if (offs == numPairs)
4382+ break;
4383+ curBack = matches[offs + 1];
4384+ if (curBack >= kNumFullDistances)
4385+ GetPosSlot2(curBack, posSlot);
4386+ }
4387+ }
4388+ }
4389+ }
4390+}
4391+
4392+#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist))
4393+
4394+static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
4395+{
4396+ UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i;
4397+ const Byte *data;
4398+ const UInt32 *matches;
4399+
4400+ if (p->additionalOffset == 0)
4401+ mainLen = ReadMatchDistances(p, &numPairs);
4402+ else
4403+ {
4404+ mainLen = p->longestMatchLength;
4405+ numPairs = p->numPairs;
4406+ }
4407+
4408+ numAvail = p->numAvail;
4409+ *backRes = (UInt32)-1;
4410+ if (numAvail < 2)
4411+ return 1;
4412+ if (numAvail > LZMA_MATCH_LEN_MAX)
4413+ numAvail = LZMA_MATCH_LEN_MAX;
4414+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
4415+
4416+ repLen = repIndex = 0;
4417+ for (i = 0; i < LZMA_NUM_REPS; i++)
4418+ {
4419+ UInt32 len;
4420+ const Byte *data2 = data - (p->reps[i] + 1);
4421+ if (data[0] != data2[0] || data[1] != data2[1])
4422+ continue;
4423+ for (len = 2; len < numAvail && data[len] == data2[len]; len++);
4424+ if (len >= p->numFastBytes)
4425+ {
4426+ *backRes = i;
4427+ MovePos(p, len - 1);
4428+ return len;
4429+ }
4430+ if (len > repLen)
4431+ {
4432+ repIndex = i;
4433+ repLen = len;
4434+ }
4435+ }
4436+
4437+ matches = p->matches;
4438+ if (mainLen >= p->numFastBytes)
4439+ {
4440+ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
4441+ MovePos(p, mainLen - 1);
4442+ return mainLen;
4443+ }
4444+
4445+ mainDist = 0; /* for GCC */
4446+ if (mainLen >= 2)
4447+ {
4448+ mainDist = matches[numPairs - 1];
4449+ while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1)
4450+ {
4451+ if (!ChangePair(matches[numPairs - 3], mainDist))
4452+ break;
4453+ numPairs -= 2;
4454+ mainLen = matches[numPairs - 2];
4455+ mainDist = matches[numPairs - 1];
4456+ }
4457+ if (mainLen == 2 && mainDist >= 0x80)
4458+ mainLen = 1;
4459+ }
4460+
4461+ if (repLen >= 2 && (
4462+ (repLen + 1 >= mainLen) ||
4463+ (repLen + 2 >= mainLen && mainDist >= (1 << 9)) ||
4464+ (repLen + 3 >= mainLen && mainDist >= (1 << 15))))
4465+ {
4466+ *backRes = repIndex;
4467+ MovePos(p, repLen - 1);
4468+ return repLen;
4469+ }
4470+
4471+ if (mainLen < 2 || numAvail <= 2)
4472+ return 1;
4473+
4474+ p->longestMatchLength = ReadMatchDistances(p, &p->numPairs);
4475+ if (p->longestMatchLength >= 2)
4476+ {
4477+ UInt32 newDistance = matches[p->numPairs - 1];
4478+ if ((p->longestMatchLength >= mainLen && newDistance < mainDist) ||
4479+ (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) ||
4480+ (p->longestMatchLength > mainLen + 1) ||
4481+ (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist)))
4482+ return 1;
4483+ }
4484+
4485+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
4486+ for (i = 0; i < LZMA_NUM_REPS; i++)
4487+ {
4488+ UInt32 len, limit;
4489+ const Byte *data2 = data - (p->reps[i] + 1);
4490+ if (data[0] != data2[0] || data[1] != data2[1])
4491+ continue;
4492+ limit = mainLen - 1;
4493+ for (len = 2; len < limit && data[len] == data2[len]; len++);
4494+ if (len >= limit)
4495+ return 1;
4496+ }
4497+ *backRes = mainDist + LZMA_NUM_REPS;
4498+ MovePos(p, mainLen - 2);
4499+ return mainLen;
4500+}
4501+
4502+static void WriteEndMarker(CLzmaEnc *p, UInt32 posState)
4503+{
4504+ UInt32 len;
4505+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
4506+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
4507+ p->state = kMatchNextStates[p->state];
4508+ len = LZMA_MATCH_LEN_MIN;
4509+ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
4510+ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1);
4511+ RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits);
4512+ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);
4513+}
4514+
4515+static SRes CheckErrors(CLzmaEnc *p)
4516+{
4517+ if (p->result != SZ_OK)
4518+ return p->result;
4519+ if (p->rc.res != SZ_OK)
4520+ p->result = SZ_ERROR_WRITE;
4521+ if (p->matchFinderBase.result != SZ_OK)
4522+ p->result = SZ_ERROR_READ;
4523+ if (p->result != SZ_OK)
4524+ p->finished = True;
4525+ return p->result;
4526+}
4527+
4528+static SRes Flush(CLzmaEnc *p, UInt32 nowPos)
4529+{
4530+ /* ReleaseMFStream(); */
4531+ p->finished = True;
4532+ if (p->writeEndMark)
4533+ WriteEndMarker(p, nowPos & p->pbMask);
4534+ RangeEnc_FlushData(&p->rc);
4535+ RangeEnc_FlushStream(&p->rc);
4536+ return CheckErrors(p);
4537+}
4538+
4539+static void FillAlignPrices(CLzmaEnc *p)
4540+{
4541+ UInt32 i;
4542+ for (i = 0; i < kAlignTableSize; i++)
4543+ p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices);
4544+ p->alignPriceCount = 0;
4545+}
4546+
4547+static void FillDistancesPrices(CLzmaEnc *p)
4548+{
4549+ UInt32 tempPrices[kNumFullDistances];
4550+ UInt32 i, lenToPosState;
4551+ for (i = kStartPosModelIndex; i < kNumFullDistances; i++)
4552+ {
4553+ UInt32 posSlot = GetPosSlot1(i);
4554+ UInt32 footerBits = ((posSlot >> 1) - 1);
4555+ UInt32 base = ((2 | (posSlot & 1)) << footerBits);
4556+ tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices);
4557+ }
4558+
4559+ for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
4560+ {
4561+ UInt32 posSlot;
4562+ const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState];
4563+ UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState];
4564+ for (posSlot = 0; posSlot < p->distTableSize; posSlot++)
4565+ posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices);
4566+ for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++)
4567+ posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits);
4568+
4569+ {
4570+ UInt32 *distancesPrices = p->distancesPrices[lenToPosState];
4571+ UInt32 i;
4572+ for (i = 0; i < kStartPosModelIndex; i++)
4573+ distancesPrices[i] = posSlotPrices[i];
4574+ for (; i < kNumFullDistances; i++)
4575+ distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i];
4576+ }
4577+ }
4578+ p->matchPriceCount = 0;
4579+}
4580+
4581+void LzmaEnc_Construct(CLzmaEnc *p)
4582+{
4583+ RangeEnc_Construct(&p->rc);
4584+ MatchFinder_Construct(&p->matchFinderBase);
4585+ #ifndef _7ZIP_ST
4586+ MatchFinderMt_Construct(&p->matchFinderMt);
4587+ p->matchFinderMt.MatchFinder = &p->matchFinderBase;
4588+ #endif
4589+
4590+ {
4591+ CLzmaEncProps props;
4592+ LzmaEncProps_Init(&props);
4593+ LzmaEnc_SetProps(p, &props);
4594+ }
4595+
4596+ #ifndef LZMA_LOG_BSR
4597+ LzmaEnc_FastPosInit(p->g_FastPos);
4598+ #endif
4599+
4600+ LzmaEnc_InitPriceTables(p->ProbPrices);
4601+ p->litProbs = 0;
4602+ p->saveState.litProbs = 0;
4603+}
4604+
4605+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
4606+{
4607+ void *p;
4608+ p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
4609+ if (p != 0)
4610+ LzmaEnc_Construct((CLzmaEnc *)p);
4611+ return p;
4612+}
4613+
4614+void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
4615+{
4616+ alloc->Free(alloc, p->litProbs);
4617+ alloc->Free(alloc, p->saveState.litProbs);
4618+ p->litProbs = 0;
4619+ p->saveState.litProbs = 0;
4620+}
4621+
4622+void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
4623+{
4624+ #ifndef _7ZIP_ST
4625+ MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
4626+ #endif
4627+ MatchFinder_Free(&p->matchFinderBase, allocBig);
4628+ LzmaEnc_FreeLits(p, alloc);
4629+ RangeEnc_Free(&p->rc, alloc);
4630+}
4631+
4632+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig)
4633+{
4634+ LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig);
4635+ alloc->Free(alloc, p);
4636+}
4637+
4638+static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)
4639+{
4640+ UInt32 nowPos32, startPos32;
4641+ if (p->needInit)
4642+ {
4643+ p->matchFinder.Init(p->matchFinderObj);
4644+ p->needInit = 0;
4645+ }
4646+
4647+ if (p->finished)
4648+ return p->result;
4649+ RINOK(CheckErrors(p));
4650+
4651+ nowPos32 = (UInt32)p->nowPos64;
4652+ startPos32 = nowPos32;
4653+
4654+ if (p->nowPos64 == 0)
4655+ {
4656+ UInt32 numPairs;
4657+ Byte curByte;
4658+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
4659+ return Flush(p, nowPos32);
4660+ ReadMatchDistances(p, &numPairs);
4661+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);
4662+ p->state = kLiteralNextStates[p->state];
4663+ curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset);
4664+ LitEnc_Encode(&p->rc, p->litProbs, curByte);
4665+ p->additionalOffset--;
4666+ nowPos32++;
4667+ }
4668+
4669+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0)
4670+ for (;;)
4671+ {
4672+ UInt32 pos, len, posState;
4673+
4674+ if (p->fastMode)
4675+ len = GetOptimumFast(p, &pos);
4676+ else
4677+ len = GetOptimum(p, nowPos32, &pos);
4678+
4679+ #ifdef SHOW_STAT2
4680+ printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos);
4681+ #endif
4682+
4683+ posState = nowPos32 & p->pbMask;
4684+ if (len == 1 && pos == (UInt32)-1)
4685+ {
4686+ Byte curByte;
4687+ CLzmaProb *probs;
4688+ const Byte *data;
4689+
4690+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0);
4691+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
4692+ curByte = *data;
4693+ probs = LIT_PROBS(nowPos32, *(data - 1));
4694+ if (IsCharState(p->state))
4695+ LitEnc_Encode(&p->rc, probs, curByte);
4696+ else
4697+ LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1));
4698+ p->state = kLiteralNextStates[p->state];
4699+ }
4700+ else
4701+ {
4702+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
4703+ if (pos < LZMA_NUM_REPS)
4704+ {
4705+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1);
4706+ if (pos == 0)
4707+ {
4708+ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0);
4709+ RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1));
4710+ }
4711+ else
4712+ {
4713+ UInt32 distance = p->reps[pos];
4714+ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1);
4715+ if (pos == 1)
4716+ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0);
4717+ else
4718+ {
4719+ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1);
4720+ RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2);
4721+ if (pos == 3)
4722+ p->reps[3] = p->reps[2];
4723+ p->reps[2] = p->reps[1];
4724+ }
4725+ p->reps[1] = p->reps[0];
4726+ p->reps[0] = distance;
4727+ }
4728+ if (len == 1)
4729+ p->state = kShortRepNextStates[p->state];
4730+ else
4731+ {
4732+ LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
4733+ p->state = kRepNextStates[p->state];
4734+ }
4735+ }
4736+ else
4737+ {
4738+ UInt32 posSlot;
4739+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
4740+ p->state = kMatchNextStates[p->state];
4741+ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
4742+ pos -= LZMA_NUM_REPS;
4743+ GetPosSlot(pos, posSlot);
4744+ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);
4745+
4746+ if (posSlot >= kStartPosModelIndex)
4747+ {
4748+ UInt32 footerBits = ((posSlot >> 1) - 1);
4749+ UInt32 base = ((2 | (posSlot & 1)) << footerBits);
4750+ UInt32 posReduced = pos - base;
4751+
4752+ if (posSlot < kEndPosModelIndex)
4753+ RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced);
4754+ else
4755+ {
4756+ RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
4757+ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);
4758+ p->alignPriceCount++;
4759+ }
4760+ }
4761+ p->reps[3] = p->reps[2];
4762+ p->reps[2] = p->reps[1];
4763+ p->reps[1] = p->reps[0];
4764+ p->reps[0] = pos;
4765+ p->matchPriceCount++;
4766+ }
4767+ }
4768+ p->additionalOffset -= len;
4769+ nowPos32 += len;
4770+ if (p->additionalOffset == 0)
4771+ {
4772+ UInt32 processed;
4773+ if (!p->fastMode)
4774+ {
4775+ if (p->matchPriceCount >= (1 << 7))
4776+ FillDistancesPrices(p);
4777+ if (p->alignPriceCount >= kAlignTableSize)
4778+ FillAlignPrices(p);
4779+ }
4780+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
4781+ break;
4782+ processed = nowPos32 - startPos32;
4783+ if (useLimits)
4784+ {
4785+ if (processed + kNumOpts + 300 >= maxUnpackSize ||
4786+ RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)
4787+ break;
4788+ }
4789+ else if (processed >= (1 << 15))
4790+ {
4791+ p->nowPos64 += nowPos32 - startPos32;
4792+ return CheckErrors(p);
4793+ }
4794+ }
4795+ }
4796+ p->nowPos64 += nowPos32 - startPos32;
4797+ return Flush(p, nowPos32);
4798+}
4799+
4800+#define kBigHashDicLimit ((UInt32)1 << 24)
4801+
4802+static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
4803+{
4804+ UInt32 beforeSize = kNumOpts;
4805+ Bool btMode;
4806+ if (!RangeEnc_Alloc(&p->rc, alloc))
4807+ return SZ_ERROR_MEM;
4808+ btMode = (p->matchFinderBase.btMode != 0);
4809+ #ifndef _7ZIP_ST
4810+ p->mtMode = (p->multiThread && !p->fastMode && btMode);
4811+ #endif
4812+
4813+ {
4814+ unsigned lclp = p->lc + p->lp;
4815+ if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp)
4816+ {
4817+ LzmaEnc_FreeLits(p, alloc);
4818+ p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
4819+ p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
4820+ if (p->litProbs == 0 || p->saveState.litProbs == 0)
4821+ {
4822+ LzmaEnc_FreeLits(p, alloc);
4823+ return SZ_ERROR_MEM;
4824+ }
4825+ p->lclp = lclp;
4826+ }
4827+ }
4828+
4829+ p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit);
4830+
4831+ if (beforeSize + p->dictSize < keepWindowSize)
4832+ beforeSize = keepWindowSize - p->dictSize;
4833+
4834+ #ifndef _7ZIP_ST
4835+ if (p->mtMode)
4836+ {
4837+ RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig));
4838+ p->matchFinderObj = &p->matchFinderMt;
4839+ MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
4840+ }
4841+ else
4842+ #endif
4843+ {
4844+ if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig))
4845+ return SZ_ERROR_MEM;
4846+ p->matchFinderObj = &p->matchFinderBase;
4847+ MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder);
4848+ }
4849+ return SZ_OK;
4850+}
4851+
4852+void LzmaEnc_Init(CLzmaEnc *p)
4853+{
4854+ UInt32 i;
4855+ p->state = 0;
4856+ for (i = 0 ; i < LZMA_NUM_REPS; i++)
4857+ p->reps[i] = 0;
4858+
4859+ RangeEnc_Init(&p->rc);
4860+
4861+
4862+ for (i = 0; i < kNumStates; i++)
4863+ {
4864+ UInt32 j;
4865+ for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++)
4866+ {
4867+ p->isMatch[i][j] = kProbInitValue;
4868+ p->isRep0Long[i][j] = kProbInitValue;
4869+ }
4870+ p->isRep[i] = kProbInitValue;
4871+ p->isRepG0[i] = kProbInitValue;
4872+ p->isRepG1[i] = kProbInitValue;
4873+ p->isRepG2[i] = kProbInitValue;
4874+ }
4875+
4876+ {
4877+ UInt32 num = 0x300 << (p->lp + p->lc);
4878+ for (i = 0; i < num; i++)
4879+ p->litProbs[i] = kProbInitValue;
4880+ }
4881+
4882+ {
4883+ for (i = 0; i < kNumLenToPosStates; i++)
4884+ {
4885+ CLzmaProb *probs = p->posSlotEncoder[i];
4886+ UInt32 j;
4887+ for (j = 0; j < (1 << kNumPosSlotBits); j++)
4888+ probs[j] = kProbInitValue;
4889+ }
4890+ }
4891+ {
4892+ for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
4893+ p->posEncoders[i] = kProbInitValue;
4894+ }
4895+
4896+ LenEnc_Init(&p->lenEnc.p);
4897+ LenEnc_Init(&p->repLenEnc.p);
4898+
4899+ for (i = 0; i < (1 << kNumAlignBits); i++)
4900+ p->posAlignEncoder[i] = kProbInitValue;
4901+
4902+ p->optimumEndIndex = 0;
4903+ p->optimumCurrentIndex = 0;
4904+ p->additionalOffset = 0;
4905+
4906+ p->pbMask = (1 << p->pb) - 1;
4907+ p->lpMask = (1 << p->lp) - 1;
4908+}
4909+
4910+void LzmaEnc_InitPrices(CLzmaEnc *p)
4911+{
4912+ if (!p->fastMode)
4913+ {
4914+ FillDistancesPrices(p);
4915+ FillAlignPrices(p);
4916+ }
4917+
4918+ p->lenEnc.tableSize =
4919+ p->repLenEnc.tableSize =
4920+ p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN;
4921+ LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices);
4922+ LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices);
4923+}
4924+
4925+static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
4926+{
4927+ UInt32 i;
4928+ for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++)
4929+ if (p->dictSize <= ((UInt32)1 << i))
4930+ break;
4931+ p->distTableSize = i * 2;
4932+
4933+ p->finished = False;
4934+ p->result = SZ_OK;
4935+ RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig));
4936+ LzmaEnc_Init(p);
4937+ LzmaEnc_InitPrices(p);
4938+ p->nowPos64 = 0;
4939+ return SZ_OK;
4940+}
4941+
4942+static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream,
4943+ ISzAlloc *alloc, ISzAlloc *allocBig)
4944+{
4945+ CLzmaEnc *p = (CLzmaEnc *)pp;
4946+ p->matchFinderBase.stream = inStream;
4947+ p->needInit = 1;
4948+ p->rc.outStream = outStream;
4949+ return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig);
4950+}
4951+
4952+SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
4953+ ISeqInStream *inStream, UInt32 keepWindowSize,
4954+ ISzAlloc *alloc, ISzAlloc *allocBig)
4955+{
4956+ CLzmaEnc *p = (CLzmaEnc *)pp;
4957+ p->matchFinderBase.stream = inStream;
4958+ p->needInit = 1;
4959+ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
4960+}
4961+
4962+static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)
4963+{
4964+ p->matchFinderBase.directInput = 1;
4965+ p->matchFinderBase.bufferBase = (Byte *)src;
4966+ p->matchFinderBase.directInputRem = srcLen;
4967+}
4968+
4969+SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
4970+ UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
4971+{
4972+ CLzmaEnc *p = (CLzmaEnc *)pp;
4973+ LzmaEnc_SetInputBuf(p, src, srcLen);
4974+ p->needInit = 1;
4975+
4976+ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
4977+}
4978+
4979+void LzmaEnc_Finish(CLzmaEncHandle pp)
4980+{
4981+ #ifndef _7ZIP_ST
4982+ CLzmaEnc *p = (CLzmaEnc *)pp;
4983+ if (p->mtMode)
4984+ MatchFinderMt_ReleaseStream(&p->matchFinderMt);
4985+ #else
4986+ pp = pp;
4987+ #endif
4988+}
4989+
4990+typedef struct
4991+{
4992+ ISeqOutStream funcTable;
4993+ Byte *data;
4994+ SizeT rem;
4995+ Bool overflow;
4996+} CSeqOutStreamBuf;
4997+
4998+static size_t MyWrite(void *pp, const void *data, size_t size)
4999+{
5000+ CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp;
5001+ if (p->rem < size)
5002+ {
5003+ size = p->rem;
5004+ p->overflow = True;
5005+ }
5006+ memcpy(p->data, data, size);
5007+ p->rem -= size;
5008+ p->data += size;
5009+ return size;
5010+}
5011+
5012+
5013+UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
5014+{
5015+ const CLzmaEnc *p = (CLzmaEnc *)pp;
5016+ return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
5017+}
5018+
5019+const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
5020+{
5021+ const CLzmaEnc *p = (CLzmaEnc *)pp;
5022+ return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
5023+}
5024+
5025+SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
5026+ Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
5027+{
5028+ CLzmaEnc *p = (CLzmaEnc *)pp;
5029+ UInt64 nowPos64;
5030+ SRes res;
5031+ CSeqOutStreamBuf outStream;
5032+
5033+ outStream.funcTable.Write = MyWrite;
5034+ outStream.data = dest;
5035+ outStream.rem = *destLen;
5036+ outStream.overflow = False;
5037+
5038+ p->writeEndMark = False;
5039+ p->finished = False;
5040+ p->result = SZ_OK;
5041+
5042+ if (reInit)
5043+ LzmaEnc_Init(p);
5044+ LzmaEnc_InitPrices(p);
5045+ nowPos64 = p->nowPos64;
5046+ RangeEnc_Init(&p->rc);
5047+ p->rc.outStream = &outStream.funcTable;
5048+
5049+ res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize);
5050+
5051+ *unpackSize = (UInt32)(p->nowPos64 - nowPos64);
5052+ *destLen -= outStream.rem;
5053+ if (outStream.overflow)
5054+ return SZ_ERROR_OUTPUT_EOF;
5055+
5056+ return res;
5057+}
5058+
5059+static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
5060+{
5061+ SRes res = SZ_OK;
5062+
5063+ #ifndef _7ZIP_ST
5064+ Byte allocaDummy[0x300];
5065+ int i = 0;
5066+ for (i = 0; i < 16; i++)
5067+ allocaDummy[i] = (Byte)i;
5068+ #endif
5069+
5070+ for (;;)
5071+ {
5072+ res = LzmaEnc_CodeOneBlock(p, False, 0, 0);
5073+ if (res != SZ_OK || p->finished != 0)
5074+ break;
5075+ if (progress != 0)
5076+ {
5077+ res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
5078+ if (res != SZ_OK)
5079+ {
5080+ res = SZ_ERROR_PROGRESS;
5081+ break;
5082+ }
5083+ }
5084+ }
5085+ LzmaEnc_Finish(p);
5086+ return res;
5087+}
5088+
5089+SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
5090+ ISzAlloc *alloc, ISzAlloc *allocBig)
5091+{
5092+ RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig));
5093+ return LzmaEnc_Encode2((CLzmaEnc *)pp, progress);
5094+}
5095+
5096+SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
5097+{
5098+ CLzmaEnc *p = (CLzmaEnc *)pp;
5099+ int i;
5100+ UInt32 dictSize = p->dictSize;
5101+ if (*size < LZMA_PROPS_SIZE)
5102+ return SZ_ERROR_PARAM;
5103+ *size = LZMA_PROPS_SIZE;
5104+ props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
5105+
5106+ for (i = 11; i <= 30; i++)
5107+ {
5108+ if (dictSize <= ((UInt32)2 << i))
5109+ {
5110+ dictSize = (2 << i);
5111+ break;
5112+ }
5113+ if (dictSize <= ((UInt32)3 << i))
5114+ {
5115+ dictSize = (3 << i);
5116+ break;
5117+ }
5118+ }
5119+
5120+ for (i = 0; i < 4; i++)
5121+ props[1 + i] = (Byte)(dictSize >> (8 * i));
5122+ return SZ_OK;
5123+}
5124+
5125+SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
5126+ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
5127+{
5128+ SRes res;
5129+ CLzmaEnc *p = (CLzmaEnc *)pp;
5130+
5131+ CSeqOutStreamBuf outStream;
5132+
5133+ LzmaEnc_SetInputBuf(p, src, srcLen);
5134+
5135+ outStream.funcTable.Write = MyWrite;
5136+ outStream.data = dest;
5137+ outStream.rem = *destLen;
5138+ outStream.overflow = False;
5139+
5140+ p->writeEndMark = writeEndMark;
5141+
5142+ p->rc.outStream = &outStream.funcTable;
5143+ res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig);
5144+ if (res == SZ_OK)
5145+ res = LzmaEnc_Encode2(p, progress);
5146+
5147+ *destLen -= outStream.rem;
5148+ if (outStream.overflow)
5149+ return SZ_ERROR_OUTPUT_EOF;
5150+ return res;
5151+}
5152+
5153+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
5154+ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
5155+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
5156+{
5157+ CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
5158+ SRes res;
5159+ if (p == 0)
5160+ return SZ_ERROR_MEM;
5161+
5162+ res = LzmaEnc_SetProps(p, props);
5163+ if (res == SZ_OK)
5164+ {
5165+ res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize);
5166+ if (res == SZ_OK)
5167+ res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen,
5168+ writeEndMark, progress, alloc, allocBig);
5169+ }
5170+
5171+ LzmaEnc_Destroy(p, alloc, allocBig);
5172+ return res;
5173+}
5174
5175Property changes on: third_party/lzma_sdk/LzmaEnc.c
5176___________________________________________________________________
5177Added: svn:eol-style
5178 + LF
5179
5180Index: third_party/lzma_sdk/Alloc.c
5181===================================================================
5182--- third_party/lzma_sdk/Alloc.c (revision 0)
5183+++ third_party/lzma_sdk/Alloc.c (revision 0)
5184@@ -0,0 +1,127 @@
5185+/* Alloc.c -- Memory allocation functions
5186+2008-09-24
5187+Igor Pavlov
5188+Public domain */
5189+
5190+#ifdef _WIN32
5191+#include <windows.h>
5192+#endif
5193+#include <stdlib.h>
5194+
5195+#include "Alloc.h"
5196+
5197+/* #define _SZ_ALLOC_DEBUG */
5198+
5199+/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
5200+#ifdef _SZ_ALLOC_DEBUG
5201+#include <stdio.h>
5202+int g_allocCount = 0;
5203+int g_allocCountMid = 0;
5204+int g_allocCountBig = 0;
5205+#endif
5206+
5207+void *MyAlloc(size_t size)
5208+{
5209+ if (size == 0)
5210+ return 0;
5211+ #ifdef _SZ_ALLOC_DEBUG
5212+ {
5213+ void *p = malloc(size);
5214+ fprintf(stderr, "\nAlloc %10d bytes, count = %10d, addr = %8X", size, g_allocCount++, (unsigned)p);
5215+ return p;
5216+ }
5217+ #else
5218+ return malloc(size);
5219+ #endif
5220+}
5221+
5222+void MyFree(void *address)
5223+{
5224+ #ifdef _SZ_ALLOC_DEBUG
5225+ if (address != 0)
5226+ fprintf(stderr, "\nFree; count = %10d, addr = %8X", --g_allocCount, (unsigned)address);
5227+ #endif
5228+ free(address);
5229+}
5230+
5231+#ifdef _WIN32
5232+
5233+void *MidAlloc(size_t size)
5234+{
5235+ if (size == 0)
5236+ return 0;
5237+ #ifdef _SZ_ALLOC_DEBUG
5238+ fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++);
5239+ #endif
5240+ return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
5241+}
5242+
5243+void MidFree(void *address)
5244+{
5245+ #ifdef _SZ_ALLOC_DEBUG
5246+ if (address != 0)
5247+ fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid);
5248+ #endif
5249+ if (address == 0)
5250+ return;
5251+ VirtualFree(address, 0, MEM_RELEASE);
5252+}
5253+
5254+#ifndef MEM_LARGE_PAGES
5255+#undef _7ZIP_LARGE_PAGES
5256+#endif
5257+
5258+#ifdef _7ZIP_LARGE_PAGES
5259+SIZE_T g_LargePageSize = 0;
5260+typedef SIZE_T (WINAPI *GetLargePageMinimumP)();
5261+#endif
5262+
5263+void SetLargePageSize()
5264+{
5265+ #ifdef _7ZIP_LARGE_PAGES
5266+ SIZE_T size = 0;
5267+ GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
5268+ GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
5269+ if (largePageMinimum == 0)
5270+ return;
5271+ size = largePageMinimum();
5272+ if (size == 0 || (size & (size - 1)) != 0)
5273+ return;
5274+ g_LargePageSize = size;
5275+ #endif
5276+}
5277+
5278+
5279+void *BigAlloc(size_t size)
5280+{
5281+ if (size == 0)
5282+ return 0;
5283+ #ifdef _SZ_ALLOC_DEBUG
5284+ fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++);
5285+ #endif
5286+
5287+ #ifdef _7ZIP_LARGE_PAGES
5288+ if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18))
5289+ {
5290+ void *res = VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)),
5291+ MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
5292+ if (res != 0)
5293+ return res;
5294+ }
5295+ #endif
5296+ return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
5297+}
5298+
5299+void BigFree(void *address)
5300+{
5301+ #ifdef _SZ_ALLOC_DEBUG
5302+ if (address != 0)
5303+ fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);
5304+ #endif
5305+
5306+ if (address == 0)
5307+ return;
5308+ VirtualFree(address, 0, MEM_RELEASE);
5309+}
5310+
5311+#endif
5312
5313Property changes on: third_party/lzma_sdk/Alloc.c
5314___________________________________________________________________
5315Added: svn:eol-style
5316 + LF
5317
5318Index: third_party/lzma_sdk/LzmaLib.c
5319===================================================================
5320--- third_party/lzma_sdk/LzmaLib.c (revision 0)
5321+++ third_party/lzma_sdk/LzmaLib.c (revision 0)
5322@@ -0,0 +1,46 @@
5323+/* LzmaLib.c -- LZMA library wrapper
5324+2008-08-05
5325+Igor Pavlov
5326+Public domain */
5327+
5328+#include "LzmaEnc.h"
5329+#include "LzmaDec.h"
5330+#include "Alloc.h"
5331+#include "LzmaLib.h"
5332+
5333+static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
5334+static void SzFree(void *p, void *address) { p = p; MyFree(address); }
5335+static ISzAlloc g_Alloc = { SzAlloc, SzFree };
5336+
5337+MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
5338+ unsigned char *outProps, size_t *outPropsSize,
5339+ int level, /* 0 <= level <= 9, default = 5 */
5340+ unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */
5341+ int lc, /* 0 <= lc <= 8, default = 3 */
5342+ int lp, /* 0 <= lp <= 4, default = 0 */
5343+ int pb, /* 0 <= pb <= 4, default = 2 */
5344+ int fb, /* 5 <= fb <= 273, default = 32 */
5345+ int numThreads /* 1 or 2, default = 2 */
5346+)
5347+{
5348+ CLzmaEncProps props;
5349+ LzmaEncProps_Init(&props);
5350+ props.level = level;
5351+ props.dictSize = dictSize;
5352+ props.lc = lc;
5353+ props.lp = lp;
5354+ props.pb = pb;
5355+ props.fb = fb;
5356+ props.numThreads = numThreads;
5357+
5358+ return LzmaEncode(dest, destLen, src, srcLen, &props, outProps, outPropsSize, 0,
5359+ NULL, &g_Alloc, &g_Alloc);
5360+}
5361+
5362+
5363+MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen,
5364+ const unsigned char *props, size_t propsSize)
5365+{
5366+ ELzmaStatus status;
5367+ return LzmaDecode(dest, destLen, src, srcLen, props, (unsigned)propsSize, LZMA_FINISH_ANY, &status, &g_Alloc);
5368+}
5369
5370Property changes on: third_party/lzma_sdk/LzmaLib.c
5371___________________________________________________________________
5372Added: svn:eol-style
5373 + LF
5374
5375Index: third_party/lzma_sdk/LzFind.h
5376===================================================================
5377--- third_party/lzma_sdk/LzFind.h (revision 0)
5378+++ third_party/lzma_sdk/LzFind.h (revision 0)
5379@@ -0,0 +1,115 @@
5380+/* LzFind.h -- Match finder for LZ algorithms
5381+2009-04-22 : Igor Pavlov : Public domain */
5382+
5383+#ifndef __LZ_FIND_H
5384+#define __LZ_FIND_H
5385+
5386+#include "Types.h"
5387+
5388+#ifdef __cplusplus
5389+extern "C" {
5390+#endif
5391+
5392+typedef UInt32 CLzRef;
5393+
5394+typedef struct _CMatchFinder
5395+{
5396+ Byte *buffer;
5397+ UInt32 pos;
5398+ UInt32 posLimit;
5399+ UInt32 streamPos;
5400+ UInt32 lenLimit;
5401+
5402+ UInt32 cyclicBufferPos;
5403+ UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
5404+
5405+ UInt32 matchMaxLen;
5406+ CLzRef *hash;
5407+ CLzRef *son;
5408+ UInt32 hashMask;
5409+ UInt32 cutValue;
5410+
5411+ Byte *bufferBase;
5412+ ISeqInStream *stream;
5413+ int streamEndWasReached;
5414+
5415+ UInt32 blockSize;
5416+ UInt32 keepSizeBefore;
5417+ UInt32 keepSizeAfter;
5418+
5419+ UInt32 numHashBytes;
5420+ int directInput;
5421+ size_t directInputRem;
5422+ int btMode;
5423+ int bigHash;
5424+ UInt32 historySize;
5425+ UInt32 fixedHashSize;
5426+ UInt32 hashSizeSum;
5427+ UInt32 numSons;
5428+ SRes result;
5429+ UInt32 crc[256];
5430+} CMatchFinder;
5431+
5432+#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
5433+#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])
5434+
5435+#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
5436+
5437+int MatchFinder_NeedMove(CMatchFinder *p);
5438+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
5439+void MatchFinder_MoveBlock(CMatchFinder *p);
5440+void MatchFinder_ReadIfRequired(CMatchFinder *p);
5441+
5442+void MatchFinder_Construct(CMatchFinder *p);
5443+
5444+/* Conditions:
5445+ historySize <= 3 GB
5446+ keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
5447+*/
5448+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
5449+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
5450+ ISzAlloc *alloc);
5451+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
5452+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
5453+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
5454+
5455+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
5456+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
5457+ UInt32 *distances, UInt32 maxLen);
5458+
5459+/*
5460+Conditions:
5461+ Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
5462+ Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
5463+*/
5464+
5465+typedef void (*Mf_Init_Func)(void *object);
5466+typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
5467+typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
5468+typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
5469+typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
5470+typedef void (*Mf_Skip_Func)(void *object, UInt32);
5471+
5472+typedef struct _IMatchFinder
5473+{
5474+ Mf_Init_Func Init;
5475+ Mf_GetIndexByte_Func GetIndexByte;
5476+ Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
5477+ Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
5478+ Mf_GetMatches_Func GetMatches;
5479+ Mf_Skip_Func Skip;
5480+} IMatchFinder;
5481+
5482+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
5483+
5484+void MatchFinder_Init(CMatchFinder *p);
5485+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
5486+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
5487+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
5488+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
5489+
5490+#ifdef __cplusplus
5491+}
5492+#endif
5493+
5494+#endif
5495
5496Property changes on: third_party/lzma_sdk/LzFind.h
5497___________________________________________________________________
5498Added: svn:eol-style
5499 + LF
5500