Root/target/linux/generic/patches-3.1/510-jffs2_make_lzma_available.patch

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

Archive Download this file



interactive