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