xref: /aosp_15_r20/external/lzma/C/LzmaEnc.c (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker /* LzmaEnc.c -- LZMA Encoder
2*f6dc9357SAndroid Build Coastguard Worker Igor Pavlov : Public domain */
3*f6dc9357SAndroid Build Coastguard Worker 
4*f6dc9357SAndroid Build Coastguard Worker #include "Precomp.h"
5*f6dc9357SAndroid Build Coastguard Worker 
6*f6dc9357SAndroid Build Coastguard Worker #include <string.h>
7*f6dc9357SAndroid Build Coastguard Worker 
8*f6dc9357SAndroid Build Coastguard Worker /* #define SHOW_STAT */
9*f6dc9357SAndroid Build Coastguard Worker /* #define SHOW_STAT2 */
10*f6dc9357SAndroid Build Coastguard Worker 
11*f6dc9357SAndroid Build Coastguard Worker #if defined(SHOW_STAT) || defined(SHOW_STAT2)
12*f6dc9357SAndroid Build Coastguard Worker #include <stdio.h>
13*f6dc9357SAndroid Build Coastguard Worker #endif
14*f6dc9357SAndroid Build Coastguard Worker 
15*f6dc9357SAndroid Build Coastguard Worker #include "CpuArch.h"
16*f6dc9357SAndroid Build Coastguard Worker #include "LzmaEnc.h"
17*f6dc9357SAndroid Build Coastguard Worker 
18*f6dc9357SAndroid Build Coastguard Worker #include "LzFind.h"
19*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
20*f6dc9357SAndroid Build Coastguard Worker #include "LzFindMt.h"
21*f6dc9357SAndroid Build Coastguard Worker #endif
22*f6dc9357SAndroid Build Coastguard Worker 
23*f6dc9357SAndroid Build Coastguard Worker /* the following LzmaEnc_* declarations is internal LZMA interface for LZMA2 encoder */
24*f6dc9357SAndroid Build Coastguard Worker 
25*f6dc9357SAndroid Build Coastguard Worker SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle p, ISeqInStreamPtr inStream, UInt32 keepWindowSize,
26*f6dc9357SAndroid Build Coastguard Worker     ISzAllocPtr alloc, ISzAllocPtr allocBig);
27*f6dc9357SAndroid Build Coastguard Worker SRes LzmaEnc_MemPrepare(CLzmaEncHandle p, const Byte *src, SizeT srcLen,
28*f6dc9357SAndroid Build Coastguard Worker     UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig);
29*f6dc9357SAndroid Build Coastguard Worker SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle p, BoolInt reInit,
30*f6dc9357SAndroid Build Coastguard Worker     Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize);
31*f6dc9357SAndroid Build Coastguard Worker const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle p);
32*f6dc9357SAndroid Build Coastguard Worker void LzmaEnc_Finish(CLzmaEncHandle p);
33*f6dc9357SAndroid Build Coastguard Worker void LzmaEnc_SaveState(CLzmaEncHandle p);
34*f6dc9357SAndroid Build Coastguard Worker void LzmaEnc_RestoreState(CLzmaEncHandle p);
35*f6dc9357SAndroid Build Coastguard Worker 
36*f6dc9357SAndroid Build Coastguard Worker #ifdef SHOW_STAT
37*f6dc9357SAndroid Build Coastguard Worker static unsigned g_STAT_OFFSET = 0;
38*f6dc9357SAndroid Build Coastguard Worker #endif
39*f6dc9357SAndroid Build Coastguard Worker 
40*f6dc9357SAndroid Build Coastguard Worker /* for good normalization speed we still reserve 256 MB before 4 GB range */
41*f6dc9357SAndroid Build Coastguard Worker #define kLzmaMaxHistorySize ((UInt32)15 << 28)
42*f6dc9357SAndroid Build Coastguard Worker 
43*f6dc9357SAndroid Build Coastguard Worker // #define kNumTopBits 24
44*f6dc9357SAndroid Build Coastguard Worker #define kTopValue ((UInt32)1 << 24)
45*f6dc9357SAndroid Build Coastguard Worker 
46*f6dc9357SAndroid Build Coastguard Worker #define kNumBitModelTotalBits 11
47*f6dc9357SAndroid Build Coastguard Worker #define kBitModelTotal (1 << kNumBitModelTotalBits)
48*f6dc9357SAndroid Build Coastguard Worker #define kNumMoveBits 5
49*f6dc9357SAndroid Build Coastguard Worker #define kProbInitValue (kBitModelTotal >> 1)
50*f6dc9357SAndroid Build Coastguard Worker 
51*f6dc9357SAndroid Build Coastguard Worker #define kNumMoveReducingBits 4
52*f6dc9357SAndroid Build Coastguard Worker #define kNumBitPriceShiftBits 4
53*f6dc9357SAndroid Build Coastguard Worker // #define kBitPrice (1 << kNumBitPriceShiftBits)
54*f6dc9357SAndroid Build Coastguard Worker 
55*f6dc9357SAndroid Build Coastguard Worker #define REP_LEN_COUNT 64
56*f6dc9357SAndroid Build Coastguard Worker 
LzmaEncProps_Init(CLzmaEncProps * p)57*f6dc9357SAndroid Build Coastguard Worker void LzmaEncProps_Init(CLzmaEncProps *p)
58*f6dc9357SAndroid Build Coastguard Worker {
59*f6dc9357SAndroid Build Coastguard Worker   p->level = 5;
60*f6dc9357SAndroid Build Coastguard Worker   p->dictSize = p->mc = 0;
61*f6dc9357SAndroid Build Coastguard Worker   p->reduceSize = (UInt64)(Int64)-1;
62*f6dc9357SAndroid Build Coastguard Worker   p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;
63*f6dc9357SAndroid Build Coastguard Worker   p->numHashOutBits = 0;
64*f6dc9357SAndroid Build Coastguard Worker   p->writeEndMark = 0;
65*f6dc9357SAndroid Build Coastguard Worker   p->affinity = 0;
66*f6dc9357SAndroid Build Coastguard Worker }
67*f6dc9357SAndroid Build Coastguard Worker 
LzmaEncProps_Normalize(CLzmaEncProps * p)68*f6dc9357SAndroid Build Coastguard Worker void LzmaEncProps_Normalize(CLzmaEncProps *p)
69*f6dc9357SAndroid Build Coastguard Worker {
70*f6dc9357SAndroid Build Coastguard Worker   int level = p->level;
71*f6dc9357SAndroid Build Coastguard Worker   if (level < 0) level = 5;
72*f6dc9357SAndroid Build Coastguard Worker   p->level = level;
73*f6dc9357SAndroid Build Coastguard Worker 
74*f6dc9357SAndroid Build Coastguard Worker   if (p->dictSize == 0)
75*f6dc9357SAndroid Build Coastguard Worker     p->dictSize = (unsigned)level <= 4 ?
76*f6dc9357SAndroid Build Coastguard Worker         (UInt32)1 << (level * 2 + 16) :
77*f6dc9357SAndroid Build Coastguard Worker         (unsigned)level <= sizeof(size_t) / 2 + 4 ?
78*f6dc9357SAndroid Build Coastguard Worker           (UInt32)1 << (level + 20) :
79*f6dc9357SAndroid Build Coastguard Worker           (UInt32)1 << (sizeof(size_t) / 2 + 24);
80*f6dc9357SAndroid Build Coastguard Worker 
81*f6dc9357SAndroid Build Coastguard Worker   if (p->dictSize > p->reduceSize)
82*f6dc9357SAndroid Build Coastguard Worker   {
83*f6dc9357SAndroid Build Coastguard Worker     UInt32 v = (UInt32)p->reduceSize;
84*f6dc9357SAndroid Build Coastguard Worker     const UInt32 kReduceMin = ((UInt32)1 << 12);
85*f6dc9357SAndroid Build Coastguard Worker     if (v < kReduceMin)
86*f6dc9357SAndroid Build Coastguard Worker       v = kReduceMin;
87*f6dc9357SAndroid Build Coastguard Worker     if (p->dictSize > v)
88*f6dc9357SAndroid Build Coastguard Worker       p->dictSize = v;
89*f6dc9357SAndroid Build Coastguard Worker   }
90*f6dc9357SAndroid Build Coastguard Worker 
91*f6dc9357SAndroid Build Coastguard Worker   if (p->lc < 0) p->lc = 3;
92*f6dc9357SAndroid Build Coastguard Worker   if (p->lp < 0) p->lp = 0;
93*f6dc9357SAndroid Build Coastguard Worker   if (p->pb < 0) p->pb = 2;
94*f6dc9357SAndroid Build Coastguard Worker 
95*f6dc9357SAndroid Build Coastguard Worker   if (p->algo < 0) p->algo = (unsigned)level < 5 ? 0 : 1;
96*f6dc9357SAndroid Build Coastguard Worker   if (p->fb < 0) p->fb = (unsigned)level < 7 ? 32 : 64;
97*f6dc9357SAndroid Build Coastguard Worker   if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
98*f6dc9357SAndroid Build Coastguard Worker   if (p->numHashBytes < 0) p->numHashBytes = (p->btMode ? 4 : 5);
99*f6dc9357SAndroid Build Coastguard Worker   if (p->mc == 0) p->mc = (16 + ((unsigned)p->fb >> 1)) >> (p->btMode ? 0 : 1);
100*f6dc9357SAndroid Build Coastguard Worker 
101*f6dc9357SAndroid Build Coastguard Worker   if (p->numThreads < 0)
102*f6dc9357SAndroid Build Coastguard Worker     p->numThreads =
103*f6dc9357SAndroid Build Coastguard Worker       #ifndef Z7_ST
104*f6dc9357SAndroid Build Coastguard Worker       ((p->btMode && p->algo) ? 2 : 1);
105*f6dc9357SAndroid Build Coastguard Worker       #else
106*f6dc9357SAndroid Build Coastguard Worker       1;
107*f6dc9357SAndroid Build Coastguard Worker       #endif
108*f6dc9357SAndroid Build Coastguard Worker }
109*f6dc9357SAndroid Build Coastguard Worker 
LzmaEncProps_GetDictSize(const CLzmaEncProps * props2)110*f6dc9357SAndroid Build Coastguard Worker UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
111*f6dc9357SAndroid Build Coastguard Worker {
112*f6dc9357SAndroid Build Coastguard Worker   CLzmaEncProps props = *props2;
113*f6dc9357SAndroid Build Coastguard Worker   LzmaEncProps_Normalize(&props);
114*f6dc9357SAndroid Build Coastguard Worker   return props.dictSize;
115*f6dc9357SAndroid Build Coastguard Worker }
116*f6dc9357SAndroid Build Coastguard Worker 
117*f6dc9357SAndroid Build Coastguard Worker 
118*f6dc9357SAndroid Build Coastguard Worker /*
119*f6dc9357SAndroid Build Coastguard Worker x86/x64:
120*f6dc9357SAndroid Build Coastguard Worker 
121*f6dc9357SAndroid Build Coastguard Worker BSR:
122*f6dc9357SAndroid Build Coastguard Worker   IF (SRC == 0) ZF = 1, DEST is undefined;
123*f6dc9357SAndroid Build Coastguard Worker                   AMD : DEST is unchanged;
124*f6dc9357SAndroid Build Coastguard Worker   IF (SRC != 0) ZF = 0; DEST is index of top non-zero bit
125*f6dc9357SAndroid Build Coastguard Worker   BSR is slow in some processors
126*f6dc9357SAndroid Build Coastguard Worker 
127*f6dc9357SAndroid Build Coastguard Worker LZCNT:
128*f6dc9357SAndroid Build Coastguard Worker   IF (SRC  == 0) CF = 1, DEST is size_in_bits_of_register(src) (32 or 64)
129*f6dc9357SAndroid Build Coastguard Worker   IF (SRC  != 0) CF = 0, DEST = num_lead_zero_bits
130*f6dc9357SAndroid Build Coastguard Worker   IF (DEST == 0) ZF = 1;
131*f6dc9357SAndroid Build Coastguard Worker 
132*f6dc9357SAndroid Build Coastguard Worker LZCNT works only in new processors starting from Haswell.
133*f6dc9357SAndroid Build Coastguard Worker if LZCNT is not supported by processor, then it's executed as BSR.
134*f6dc9357SAndroid Build Coastguard Worker LZCNT can be faster than BSR, if supported.
135*f6dc9357SAndroid Build Coastguard Worker */
136*f6dc9357SAndroid Build Coastguard Worker 
137*f6dc9357SAndroid Build Coastguard Worker // #define LZMA_LOG_BSR
138*f6dc9357SAndroid Build Coastguard Worker 
139*f6dc9357SAndroid Build Coastguard Worker #if defined(MY_CPU_ARM_OR_ARM64) /* || defined(MY_CPU_X86_OR_AMD64) */
140*f6dc9357SAndroid Build Coastguard Worker 
141*f6dc9357SAndroid Build Coastguard Worker   #if (defined(__clang__) && (__clang_major__ >= 6)) \
142*f6dc9357SAndroid Build Coastguard Worker       || (defined(__GNUC__) && (__GNUC__ >= 6))
143*f6dc9357SAndroid Build Coastguard Worker       #define LZMA_LOG_BSR
144*f6dc9357SAndroid Build Coastguard Worker   #elif defined(_MSC_VER) && (_MSC_VER >= 1300)
145*f6dc9357SAndroid Build Coastguard Worker     // #if defined(MY_CPU_ARM_OR_ARM64)
146*f6dc9357SAndroid Build Coastguard Worker       #define LZMA_LOG_BSR
147*f6dc9357SAndroid Build Coastguard Worker     // #endif
148*f6dc9357SAndroid Build Coastguard Worker   #endif
149*f6dc9357SAndroid Build Coastguard Worker #endif
150*f6dc9357SAndroid Build Coastguard Worker 
151*f6dc9357SAndroid Build Coastguard Worker // #include <intrin.h>
152*f6dc9357SAndroid Build Coastguard Worker 
153*f6dc9357SAndroid Build Coastguard Worker #ifdef LZMA_LOG_BSR
154*f6dc9357SAndroid Build Coastguard Worker 
155*f6dc9357SAndroid Build Coastguard Worker #if defined(__clang__) \
156*f6dc9357SAndroid Build Coastguard Worker     || defined(__GNUC__)
157*f6dc9357SAndroid Build Coastguard Worker 
158*f6dc9357SAndroid Build Coastguard Worker /*
159*f6dc9357SAndroid Build Coastguard Worker   C code:                  : (30 - __builtin_clz(x))
160*f6dc9357SAndroid Build Coastguard Worker     gcc9/gcc10 for x64 /x86  : 30 - (bsr(x) xor 31)
161*f6dc9357SAndroid Build Coastguard Worker     clang10 for x64          : 31 + (bsr(x) xor -32)
162*f6dc9357SAndroid Build Coastguard Worker */
163*f6dc9357SAndroid Build Coastguard Worker 
164*f6dc9357SAndroid Build Coastguard Worker   #define MY_clz(x)  ((unsigned)__builtin_clz(x))
165*f6dc9357SAndroid Build Coastguard Worker   // __lzcnt32
166*f6dc9357SAndroid Build Coastguard Worker   // __builtin_ia32_lzcnt_u32
167*f6dc9357SAndroid Build Coastguard Worker 
168*f6dc9357SAndroid Build Coastguard Worker #else  // #if defined(_MSC_VER)
169*f6dc9357SAndroid Build Coastguard Worker 
170*f6dc9357SAndroid Build Coastguard Worker   #ifdef MY_CPU_ARM_OR_ARM64
171*f6dc9357SAndroid Build Coastguard Worker 
172*f6dc9357SAndroid Build Coastguard Worker     #define MY_clz  _CountLeadingZeros
173*f6dc9357SAndroid Build Coastguard Worker 
174*f6dc9357SAndroid Build Coastguard Worker   #else // if defined(MY_CPU_X86_OR_AMD64)
175*f6dc9357SAndroid Build Coastguard Worker 
176*f6dc9357SAndroid Build Coastguard Worker     // #define MY_clz  __lzcnt  // we can use lzcnt (unsupported by old CPU)
177*f6dc9357SAndroid Build Coastguard Worker     // _BitScanReverse code is not optimal for some MSVC compilers
178*f6dc9357SAndroid Build Coastguard Worker     #define BSR2_RET(pos, res) { unsigned long zz; _BitScanReverse(&zz, (pos)); zz--; \
179*f6dc9357SAndroid Build Coastguard Worker       res = (zz + zz) + (pos >> zz); }
180*f6dc9357SAndroid Build Coastguard Worker 
181*f6dc9357SAndroid Build Coastguard Worker   #endif // MY_CPU_X86_OR_AMD64
182*f6dc9357SAndroid Build Coastguard Worker 
183*f6dc9357SAndroid Build Coastguard Worker #endif // _MSC_VER
184*f6dc9357SAndroid Build Coastguard Worker 
185*f6dc9357SAndroid Build Coastguard Worker 
186*f6dc9357SAndroid Build Coastguard Worker #ifndef BSR2_RET
187*f6dc9357SAndroid Build Coastguard Worker 
188*f6dc9357SAndroid Build Coastguard Worker     #define BSR2_RET(pos, res) { unsigned zz = 30 - MY_clz(pos); \
189*f6dc9357SAndroid Build Coastguard Worker       res = (zz + zz) + (pos >> zz); }
190*f6dc9357SAndroid Build Coastguard Worker 
191*f6dc9357SAndroid Build Coastguard Worker #endif
192*f6dc9357SAndroid Build Coastguard Worker 
193*f6dc9357SAndroid Build Coastguard Worker 
194*f6dc9357SAndroid Build Coastguard Worker unsigned GetPosSlot1(UInt32 pos);
GetPosSlot1(UInt32 pos)195*f6dc9357SAndroid Build Coastguard Worker unsigned GetPosSlot1(UInt32 pos)
196*f6dc9357SAndroid Build Coastguard Worker {
197*f6dc9357SAndroid Build Coastguard Worker   unsigned res;
198*f6dc9357SAndroid Build Coastguard Worker   BSR2_RET(pos, res)
199*f6dc9357SAndroid Build Coastguard Worker   return res;
200*f6dc9357SAndroid Build Coastguard Worker }
201*f6dc9357SAndroid Build Coastguard Worker #define GetPosSlot2(pos, res) { BSR2_RET(pos, res) }
202*f6dc9357SAndroid Build Coastguard Worker #define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res) }
203*f6dc9357SAndroid Build Coastguard Worker 
204*f6dc9357SAndroid Build Coastguard Worker 
205*f6dc9357SAndroid Build Coastguard Worker #else // ! LZMA_LOG_BSR
206*f6dc9357SAndroid Build Coastguard Worker 
207*f6dc9357SAndroid Build Coastguard Worker #define kNumLogBits (11 + sizeof(size_t) / 8 * 3)
208*f6dc9357SAndroid Build Coastguard Worker 
209*f6dc9357SAndroid Build Coastguard Worker #define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
210*f6dc9357SAndroid Build Coastguard Worker 
LzmaEnc_FastPosInit(Byte * g_FastPos)211*f6dc9357SAndroid Build Coastguard Worker static void LzmaEnc_FastPosInit(Byte *g_FastPos)
212*f6dc9357SAndroid Build Coastguard Worker {
213*f6dc9357SAndroid Build Coastguard Worker   unsigned slot;
214*f6dc9357SAndroid Build Coastguard Worker   g_FastPos[0] = 0;
215*f6dc9357SAndroid Build Coastguard Worker   g_FastPos[1] = 1;
216*f6dc9357SAndroid Build Coastguard Worker   g_FastPos += 2;
217*f6dc9357SAndroid Build Coastguard Worker 
218*f6dc9357SAndroid Build Coastguard Worker   for (slot = 2; slot < kNumLogBits * 2; slot++)
219*f6dc9357SAndroid Build Coastguard Worker   {
220*f6dc9357SAndroid Build Coastguard Worker     size_t k = ((size_t)1 << ((slot >> 1) - 1));
221*f6dc9357SAndroid Build Coastguard Worker     size_t j;
222*f6dc9357SAndroid Build Coastguard Worker     for (j = 0; j < k; j++)
223*f6dc9357SAndroid Build Coastguard Worker       g_FastPos[j] = (Byte)slot;
224*f6dc9357SAndroid Build Coastguard Worker     g_FastPos += k;
225*f6dc9357SAndroid Build Coastguard Worker   }
226*f6dc9357SAndroid Build Coastguard Worker }
227*f6dc9357SAndroid Build Coastguard Worker 
228*f6dc9357SAndroid Build Coastguard Worker /* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */
229*f6dc9357SAndroid Build Coastguard Worker /*
230*f6dc9357SAndroid Build Coastguard Worker #define BSR2_RET(pos, res) { unsigned zz = 6 + ((kNumLogBits - 1) & \
231*f6dc9357SAndroid Build Coastguard Worker   (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
232*f6dc9357SAndroid Build Coastguard Worker   res = p->g_FastPos[pos >> zz] + (zz * 2); }
233*f6dc9357SAndroid Build Coastguard Worker */
234*f6dc9357SAndroid Build Coastguard Worker 
235*f6dc9357SAndroid Build Coastguard Worker /*
236*f6dc9357SAndroid Build Coastguard Worker #define BSR2_RET(pos, res) { unsigned zz = 6 + ((kNumLogBits - 1) & \
237*f6dc9357SAndroid Build Coastguard Worker   (0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \
238*f6dc9357SAndroid Build Coastguard Worker   res = p->g_FastPos[pos >> zz] + (zz * 2); }
239*f6dc9357SAndroid Build Coastguard Worker */
240*f6dc9357SAndroid Build Coastguard Worker 
241*f6dc9357SAndroid Build Coastguard Worker #define BSR2_RET(pos, res) { unsigned zz = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \
242*f6dc9357SAndroid Build Coastguard Worker   res = p->g_FastPos[pos >> zz] + (zz * 2); }
243*f6dc9357SAndroid Build Coastguard Worker 
244*f6dc9357SAndroid Build Coastguard Worker /*
245*f6dc9357SAndroid Build Coastguard Worker #define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
246*f6dc9357SAndroid Build Coastguard Worker   p->g_FastPos[pos >> 6] + 12 : \
247*f6dc9357SAndroid Build Coastguard Worker   p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; }
248*f6dc9357SAndroid Build Coastguard Worker */
249*f6dc9357SAndroid Build Coastguard Worker 
250*f6dc9357SAndroid Build Coastguard Worker #define GetPosSlot1(pos) p->g_FastPos[pos]
251*f6dc9357SAndroid Build Coastguard Worker #define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
252*f6dc9357SAndroid Build Coastguard Worker #define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos & (kNumFullDistances - 1)]; else BSR2_RET(pos, res); }
253*f6dc9357SAndroid Build Coastguard Worker 
254*f6dc9357SAndroid Build Coastguard Worker #endif // LZMA_LOG_BSR
255*f6dc9357SAndroid Build Coastguard Worker 
256*f6dc9357SAndroid Build Coastguard Worker 
257*f6dc9357SAndroid Build Coastguard Worker #define LZMA_NUM_REPS 4
258*f6dc9357SAndroid Build Coastguard Worker 
259*f6dc9357SAndroid Build Coastguard Worker typedef UInt16 CState;
260*f6dc9357SAndroid Build Coastguard Worker typedef UInt16 CExtra;
261*f6dc9357SAndroid Build Coastguard Worker 
262*f6dc9357SAndroid Build Coastguard Worker typedef struct
263*f6dc9357SAndroid Build Coastguard Worker {
264*f6dc9357SAndroid Build Coastguard Worker   UInt32 price;
265*f6dc9357SAndroid Build Coastguard Worker   CState state;
266*f6dc9357SAndroid Build Coastguard Worker   CExtra extra;
267*f6dc9357SAndroid Build Coastguard Worker       // 0   : normal
268*f6dc9357SAndroid Build Coastguard Worker       // 1   : LIT : MATCH
269*f6dc9357SAndroid Build Coastguard Worker       // > 1 : MATCH (extra-1) : LIT : REP0 (len)
270*f6dc9357SAndroid Build Coastguard Worker   UInt32 len;
271*f6dc9357SAndroid Build Coastguard Worker   UInt32 dist;
272*f6dc9357SAndroid Build Coastguard Worker   UInt32 reps[LZMA_NUM_REPS];
273*f6dc9357SAndroid Build Coastguard Worker } COptimal;
274*f6dc9357SAndroid Build Coastguard Worker 
275*f6dc9357SAndroid Build Coastguard Worker 
276*f6dc9357SAndroid Build Coastguard Worker // 18.06
277*f6dc9357SAndroid Build Coastguard Worker #define kNumOpts (1 << 11)
278*f6dc9357SAndroid Build Coastguard Worker #define kPackReserve (kNumOpts * 8)
279*f6dc9357SAndroid Build Coastguard Worker // #define kNumOpts (1 << 12)
280*f6dc9357SAndroid Build Coastguard Worker // #define kPackReserve (1 + kNumOpts * 2)
281*f6dc9357SAndroid Build Coastguard Worker 
282*f6dc9357SAndroid Build Coastguard Worker #define kNumLenToPosStates 4
283*f6dc9357SAndroid Build Coastguard Worker #define kNumPosSlotBits 6
284*f6dc9357SAndroid Build Coastguard Worker // #define kDicLogSizeMin 0
285*f6dc9357SAndroid Build Coastguard Worker #define kDicLogSizeMax 32
286*f6dc9357SAndroid Build Coastguard Worker #define kDistTableSizeMax (kDicLogSizeMax * 2)
287*f6dc9357SAndroid Build Coastguard Worker 
288*f6dc9357SAndroid Build Coastguard Worker #define kNumAlignBits 4
289*f6dc9357SAndroid Build Coastguard Worker #define kAlignTableSize (1 << kNumAlignBits)
290*f6dc9357SAndroid Build Coastguard Worker #define kAlignMask (kAlignTableSize - 1)
291*f6dc9357SAndroid Build Coastguard Worker 
292*f6dc9357SAndroid Build Coastguard Worker #define kStartPosModelIndex 4
293*f6dc9357SAndroid Build Coastguard Worker #define kEndPosModelIndex 14
294*f6dc9357SAndroid Build Coastguard Worker #define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
295*f6dc9357SAndroid Build Coastguard Worker 
296*f6dc9357SAndroid Build Coastguard Worker typedef
297*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_LZMA_PROB32
298*f6dc9357SAndroid Build Coastguard Worker   UInt32
299*f6dc9357SAndroid Build Coastguard Worker #else
300*f6dc9357SAndroid Build Coastguard Worker   UInt16
301*f6dc9357SAndroid Build Coastguard Worker #endif
302*f6dc9357SAndroid Build Coastguard Worker   CLzmaProb;
303*f6dc9357SAndroid Build Coastguard Worker 
304*f6dc9357SAndroid Build Coastguard Worker #define LZMA_PB_MAX 4
305*f6dc9357SAndroid Build Coastguard Worker #define LZMA_LC_MAX 8
306*f6dc9357SAndroid Build Coastguard Worker #define LZMA_LP_MAX 4
307*f6dc9357SAndroid Build Coastguard Worker 
308*f6dc9357SAndroid Build Coastguard Worker #define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX)
309*f6dc9357SAndroid Build Coastguard Worker 
310*f6dc9357SAndroid Build Coastguard Worker #define kLenNumLowBits 3
311*f6dc9357SAndroid Build Coastguard Worker #define kLenNumLowSymbols (1 << kLenNumLowBits)
312*f6dc9357SAndroid Build Coastguard Worker #define kLenNumHighBits 8
313*f6dc9357SAndroid Build Coastguard Worker #define kLenNumHighSymbols (1 << kLenNumHighBits)
314*f6dc9357SAndroid Build Coastguard Worker #define kLenNumSymbolsTotal (kLenNumLowSymbols * 2 + kLenNumHighSymbols)
315*f6dc9357SAndroid Build Coastguard Worker 
316*f6dc9357SAndroid Build Coastguard Worker #define LZMA_MATCH_LEN_MIN 2
317*f6dc9357SAndroid Build Coastguard Worker #define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1)
318*f6dc9357SAndroid Build Coastguard Worker 
319*f6dc9357SAndroid Build Coastguard Worker #define kNumStates 12
320*f6dc9357SAndroid Build Coastguard Worker 
321*f6dc9357SAndroid Build Coastguard Worker 
322*f6dc9357SAndroid Build Coastguard Worker typedef struct
323*f6dc9357SAndroid Build Coastguard Worker {
324*f6dc9357SAndroid Build Coastguard Worker   CLzmaProb low[LZMA_NUM_PB_STATES_MAX << (kLenNumLowBits + 1)];
325*f6dc9357SAndroid Build Coastguard Worker   CLzmaProb high[kLenNumHighSymbols];
326*f6dc9357SAndroid Build Coastguard Worker } CLenEnc;
327*f6dc9357SAndroid Build Coastguard Worker 
328*f6dc9357SAndroid Build Coastguard Worker 
329*f6dc9357SAndroid Build Coastguard Worker typedef struct
330*f6dc9357SAndroid Build Coastguard Worker {
331*f6dc9357SAndroid Build Coastguard Worker   unsigned tableSize;
332*f6dc9357SAndroid Build Coastguard Worker   UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
333*f6dc9357SAndroid Build Coastguard Worker   // UInt32 prices1[LZMA_NUM_PB_STATES_MAX][kLenNumLowSymbols * 2];
334*f6dc9357SAndroid Build Coastguard Worker   // UInt32 prices2[kLenNumSymbolsTotal];
335*f6dc9357SAndroid Build Coastguard Worker } CLenPriceEnc;
336*f6dc9357SAndroid Build Coastguard Worker 
337*f6dc9357SAndroid Build Coastguard Worker #define GET_PRICE_LEN(p, posState, len) \
338*f6dc9357SAndroid Build Coastguard Worker     ((p)->prices[posState][(size_t)(len) - LZMA_MATCH_LEN_MIN])
339*f6dc9357SAndroid Build Coastguard Worker 
340*f6dc9357SAndroid Build Coastguard Worker /*
341*f6dc9357SAndroid Build Coastguard Worker #define GET_PRICE_LEN(p, posState, len) \
342*f6dc9357SAndroid Build Coastguard Worker     ((p)->prices2[(size_t)(len) - 2] + ((p)->prices1[posState][((len) - 2) & (kLenNumLowSymbols * 2 - 1)] & (((len) - 2 - kLenNumLowSymbols * 2) >> 9)))
343*f6dc9357SAndroid Build Coastguard Worker */
344*f6dc9357SAndroid Build Coastguard Worker 
345*f6dc9357SAndroid Build Coastguard Worker typedef struct
346*f6dc9357SAndroid Build Coastguard Worker {
347*f6dc9357SAndroid Build Coastguard Worker   UInt32 range;
348*f6dc9357SAndroid Build Coastguard Worker   unsigned cache;
349*f6dc9357SAndroid Build Coastguard Worker   UInt64 low;
350*f6dc9357SAndroid Build Coastguard Worker   UInt64 cacheSize;
351*f6dc9357SAndroid Build Coastguard Worker   Byte *buf;
352*f6dc9357SAndroid Build Coastguard Worker   Byte *bufLim;
353*f6dc9357SAndroid Build Coastguard Worker   Byte *bufBase;
354*f6dc9357SAndroid Build Coastguard Worker   ISeqOutStreamPtr outStream;
355*f6dc9357SAndroid Build Coastguard Worker   UInt64 processed;
356*f6dc9357SAndroid Build Coastguard Worker   SRes res;
357*f6dc9357SAndroid Build Coastguard Worker } CRangeEnc;
358*f6dc9357SAndroid Build Coastguard Worker 
359*f6dc9357SAndroid Build Coastguard Worker 
360*f6dc9357SAndroid Build Coastguard Worker typedef struct
361*f6dc9357SAndroid Build Coastguard Worker {
362*f6dc9357SAndroid Build Coastguard Worker   CLzmaProb *litProbs;
363*f6dc9357SAndroid Build Coastguard Worker 
364*f6dc9357SAndroid Build Coastguard Worker   unsigned state;
365*f6dc9357SAndroid Build Coastguard Worker   UInt32 reps[LZMA_NUM_REPS];
366*f6dc9357SAndroid Build Coastguard Worker 
367*f6dc9357SAndroid Build Coastguard Worker   CLzmaProb posAlignEncoder[1 << kNumAlignBits];
368*f6dc9357SAndroid Build Coastguard Worker   CLzmaProb isRep[kNumStates];
369*f6dc9357SAndroid Build Coastguard Worker   CLzmaProb isRepG0[kNumStates];
370*f6dc9357SAndroid Build Coastguard Worker   CLzmaProb isRepG1[kNumStates];
371*f6dc9357SAndroid Build Coastguard Worker   CLzmaProb isRepG2[kNumStates];
372*f6dc9357SAndroid Build Coastguard Worker   CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
373*f6dc9357SAndroid Build Coastguard Worker   CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
374*f6dc9357SAndroid Build Coastguard Worker 
375*f6dc9357SAndroid Build Coastguard Worker   CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
376*f6dc9357SAndroid Build Coastguard Worker   CLzmaProb posEncoders[kNumFullDistances];
377*f6dc9357SAndroid Build Coastguard Worker 
378*f6dc9357SAndroid Build Coastguard Worker   CLenEnc lenProbs;
379*f6dc9357SAndroid Build Coastguard Worker   CLenEnc repLenProbs;
380*f6dc9357SAndroid Build Coastguard Worker 
381*f6dc9357SAndroid Build Coastguard Worker } CSaveState;
382*f6dc9357SAndroid Build Coastguard Worker 
383*f6dc9357SAndroid Build Coastguard Worker 
384*f6dc9357SAndroid Build Coastguard Worker typedef UInt32 CProbPrice;
385*f6dc9357SAndroid Build Coastguard Worker 
386*f6dc9357SAndroid Build Coastguard Worker 
387*f6dc9357SAndroid Build Coastguard Worker struct CLzmaEnc
388*f6dc9357SAndroid Build Coastguard Worker {
389*f6dc9357SAndroid Build Coastguard Worker   void *matchFinderObj;
390*f6dc9357SAndroid Build Coastguard Worker   IMatchFinder2 matchFinder;
391*f6dc9357SAndroid Build Coastguard Worker 
392*f6dc9357SAndroid Build Coastguard Worker   unsigned optCur;
393*f6dc9357SAndroid Build Coastguard Worker   unsigned optEnd;
394*f6dc9357SAndroid Build Coastguard Worker 
395*f6dc9357SAndroid Build Coastguard Worker   unsigned longestMatchLen;
396*f6dc9357SAndroid Build Coastguard Worker   unsigned numPairs;
397*f6dc9357SAndroid Build Coastguard Worker   UInt32 numAvail;
398*f6dc9357SAndroid Build Coastguard Worker 
399*f6dc9357SAndroid Build Coastguard Worker   unsigned state;
400*f6dc9357SAndroid Build Coastguard Worker   unsigned numFastBytes;
401*f6dc9357SAndroid Build Coastguard Worker   unsigned additionalOffset;
402*f6dc9357SAndroid Build Coastguard Worker   UInt32 reps[LZMA_NUM_REPS];
403*f6dc9357SAndroid Build Coastguard Worker   unsigned lpMask, pbMask;
404*f6dc9357SAndroid Build Coastguard Worker   CLzmaProb *litProbs;
405*f6dc9357SAndroid Build Coastguard Worker   CRangeEnc rc;
406*f6dc9357SAndroid Build Coastguard Worker 
407*f6dc9357SAndroid Build Coastguard Worker   UInt32 backRes;
408*f6dc9357SAndroid Build Coastguard Worker 
409*f6dc9357SAndroid Build Coastguard Worker   unsigned lc, lp, pb;
410*f6dc9357SAndroid Build Coastguard Worker   unsigned lclp;
411*f6dc9357SAndroid Build Coastguard Worker 
412*f6dc9357SAndroid Build Coastguard Worker   BoolInt fastMode;
413*f6dc9357SAndroid Build Coastguard Worker   BoolInt writeEndMark;
414*f6dc9357SAndroid Build Coastguard Worker   BoolInt finished;
415*f6dc9357SAndroid Build Coastguard Worker   BoolInt multiThread;
416*f6dc9357SAndroid Build Coastguard Worker   BoolInt needInit;
417*f6dc9357SAndroid Build Coastguard Worker   // BoolInt _maxMode;
418*f6dc9357SAndroid Build Coastguard Worker 
419*f6dc9357SAndroid Build Coastguard Worker   UInt64 nowPos64;
420*f6dc9357SAndroid Build Coastguard Worker 
421*f6dc9357SAndroid Build Coastguard Worker   unsigned matchPriceCount;
422*f6dc9357SAndroid Build Coastguard Worker   // unsigned alignPriceCount;
423*f6dc9357SAndroid Build Coastguard Worker   int repLenEncCounter;
424*f6dc9357SAndroid Build Coastguard Worker 
425*f6dc9357SAndroid Build Coastguard Worker   unsigned distTableSize;
426*f6dc9357SAndroid Build Coastguard Worker 
427*f6dc9357SAndroid Build Coastguard Worker   UInt32 dictSize;
428*f6dc9357SAndroid Build Coastguard Worker   SRes result;
429*f6dc9357SAndroid Build Coastguard Worker 
430*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
431*f6dc9357SAndroid Build Coastguard Worker   BoolInt mtMode;
432*f6dc9357SAndroid Build Coastguard Worker   // begin of CMatchFinderMt is used in LZ thread
433*f6dc9357SAndroid Build Coastguard Worker   CMatchFinderMt matchFinderMt;
434*f6dc9357SAndroid Build Coastguard Worker   // end of CMatchFinderMt is used in BT and HASH threads
435*f6dc9357SAndroid Build Coastguard Worker   // #else
436*f6dc9357SAndroid Build Coastguard Worker   // CMatchFinder matchFinderBase;
437*f6dc9357SAndroid Build Coastguard Worker   #endif
438*f6dc9357SAndroid Build Coastguard Worker   CMatchFinder matchFinderBase;
439*f6dc9357SAndroid Build Coastguard Worker 
440*f6dc9357SAndroid Build Coastguard Worker 
441*f6dc9357SAndroid Build Coastguard Worker   // we suppose that we have 8-bytes alignment after CMatchFinder
442*f6dc9357SAndroid Build Coastguard Worker 
443*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
444*f6dc9357SAndroid Build Coastguard Worker   Byte pad[128];
445*f6dc9357SAndroid Build Coastguard Worker   #endif
446*f6dc9357SAndroid Build Coastguard Worker 
447*f6dc9357SAndroid Build Coastguard Worker   // LZ thread
448*f6dc9357SAndroid Build Coastguard Worker   CProbPrice ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
449*f6dc9357SAndroid Build Coastguard Worker 
450*f6dc9357SAndroid Build Coastguard Worker   // we want {len , dist} pairs to be 8-bytes aligned in matches array
451*f6dc9357SAndroid Build Coastguard Worker   UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2];
452*f6dc9357SAndroid Build Coastguard Worker 
453*f6dc9357SAndroid Build Coastguard Worker   // we want 8-bytes alignment here
454*f6dc9357SAndroid Build Coastguard Worker   UInt32 alignPrices[kAlignTableSize];
455*f6dc9357SAndroid Build Coastguard Worker   UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
456*f6dc9357SAndroid Build Coastguard Worker   UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
457*f6dc9357SAndroid Build Coastguard Worker 
458*f6dc9357SAndroid Build Coastguard Worker   CLzmaProb posAlignEncoder[1 << kNumAlignBits];
459*f6dc9357SAndroid Build Coastguard Worker   CLzmaProb isRep[kNumStates];
460*f6dc9357SAndroid Build Coastguard Worker   CLzmaProb isRepG0[kNumStates];
461*f6dc9357SAndroid Build Coastguard Worker   CLzmaProb isRepG1[kNumStates];
462*f6dc9357SAndroid Build Coastguard Worker   CLzmaProb isRepG2[kNumStates];
463*f6dc9357SAndroid Build Coastguard Worker   CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
464*f6dc9357SAndroid Build Coastguard Worker   CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
465*f6dc9357SAndroid Build Coastguard Worker   CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
466*f6dc9357SAndroid Build Coastguard Worker   CLzmaProb posEncoders[kNumFullDistances];
467*f6dc9357SAndroid Build Coastguard Worker 
468*f6dc9357SAndroid Build Coastguard Worker   CLenEnc lenProbs;
469*f6dc9357SAndroid Build Coastguard Worker   CLenEnc repLenProbs;
470*f6dc9357SAndroid Build Coastguard Worker 
471*f6dc9357SAndroid Build Coastguard Worker   #ifndef LZMA_LOG_BSR
472*f6dc9357SAndroid Build Coastguard Worker   Byte g_FastPos[1 << kNumLogBits];
473*f6dc9357SAndroid Build Coastguard Worker   #endif
474*f6dc9357SAndroid Build Coastguard Worker 
475*f6dc9357SAndroid Build Coastguard Worker   CLenPriceEnc lenEnc;
476*f6dc9357SAndroid Build Coastguard Worker   CLenPriceEnc repLenEnc;
477*f6dc9357SAndroid Build Coastguard Worker 
478*f6dc9357SAndroid Build Coastguard Worker   COptimal opt[kNumOpts];
479*f6dc9357SAndroid Build Coastguard Worker 
480*f6dc9357SAndroid Build Coastguard Worker   CSaveState saveState;
481*f6dc9357SAndroid Build Coastguard Worker 
482*f6dc9357SAndroid Build Coastguard Worker   // BoolInt mf_Failure;
483*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
484*f6dc9357SAndroid Build Coastguard Worker   Byte pad2[128];
485*f6dc9357SAndroid Build Coastguard Worker   #endif
486*f6dc9357SAndroid Build Coastguard Worker };
487*f6dc9357SAndroid Build Coastguard Worker 
488*f6dc9357SAndroid Build Coastguard Worker 
489*f6dc9357SAndroid Build Coastguard Worker #define MFB (p->matchFinderBase)
490*f6dc9357SAndroid Build Coastguard Worker /*
491*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
492*f6dc9357SAndroid Build Coastguard Worker #define MFB (p->matchFinderMt.MatchFinder)
493*f6dc9357SAndroid Build Coastguard Worker #endif
494*f6dc9357SAndroid Build Coastguard Worker */
495*f6dc9357SAndroid Build Coastguard Worker 
496*f6dc9357SAndroid Build Coastguard Worker // #define GET_CLzmaEnc_p  CLzmaEnc *p = (CLzmaEnc*)(void *)p;
497*f6dc9357SAndroid Build Coastguard Worker // #define GET_const_CLzmaEnc_p  const CLzmaEnc *p = (const CLzmaEnc*)(const void *)p;
498*f6dc9357SAndroid Build Coastguard Worker 
499*f6dc9357SAndroid Build Coastguard Worker #define COPY_ARR(dest, src, arr)  memcpy((dest)->arr, (src)->arr, sizeof((src)->arr));
500*f6dc9357SAndroid Build Coastguard Worker 
501*f6dc9357SAndroid Build Coastguard Worker #define COPY_LZMA_ENC_STATE(d, s, p)  \
502*f6dc9357SAndroid Build Coastguard Worker   (d)->state = (s)->state;  \
503*f6dc9357SAndroid Build Coastguard Worker   COPY_ARR(d, s, reps)  \
504*f6dc9357SAndroid Build Coastguard Worker   COPY_ARR(d, s, posAlignEncoder)  \
505*f6dc9357SAndroid Build Coastguard Worker   COPY_ARR(d, s, isRep)  \
506*f6dc9357SAndroid Build Coastguard Worker   COPY_ARR(d, s, isRepG0)  \
507*f6dc9357SAndroid Build Coastguard Worker   COPY_ARR(d, s, isRepG1)  \
508*f6dc9357SAndroid Build Coastguard Worker   COPY_ARR(d, s, isRepG2)  \
509*f6dc9357SAndroid Build Coastguard Worker   COPY_ARR(d, s, isMatch)  \
510*f6dc9357SAndroid Build Coastguard Worker   COPY_ARR(d, s, isRep0Long)  \
511*f6dc9357SAndroid Build Coastguard Worker   COPY_ARR(d, s, posSlotEncoder)  \
512*f6dc9357SAndroid Build Coastguard Worker   COPY_ARR(d, s, posEncoders)  \
513*f6dc9357SAndroid Build Coastguard Worker   (d)->lenProbs = (s)->lenProbs;  \
514*f6dc9357SAndroid Build Coastguard Worker   (d)->repLenProbs = (s)->repLenProbs;  \
515*f6dc9357SAndroid Build Coastguard Worker   memcpy((d)->litProbs, (s)->litProbs, ((size_t)0x300 * sizeof(CLzmaProb)) << (p)->lclp);
516*f6dc9357SAndroid Build Coastguard Worker 
LzmaEnc_SaveState(CLzmaEncHandle p)517*f6dc9357SAndroid Build Coastguard Worker void LzmaEnc_SaveState(CLzmaEncHandle p)
518*f6dc9357SAndroid Build Coastguard Worker {
519*f6dc9357SAndroid Build Coastguard Worker   // GET_CLzmaEnc_p
520*f6dc9357SAndroid Build Coastguard Worker   CSaveState *v = &p->saveState;
521*f6dc9357SAndroid Build Coastguard Worker   COPY_LZMA_ENC_STATE(v, p, p)
522*f6dc9357SAndroid Build Coastguard Worker }
523*f6dc9357SAndroid Build Coastguard Worker 
LzmaEnc_RestoreState(CLzmaEncHandle p)524*f6dc9357SAndroid Build Coastguard Worker void LzmaEnc_RestoreState(CLzmaEncHandle p)
525*f6dc9357SAndroid Build Coastguard Worker {
526*f6dc9357SAndroid Build Coastguard Worker   // GET_CLzmaEnc_p
527*f6dc9357SAndroid Build Coastguard Worker   const CSaveState *v = &p->saveState;
528*f6dc9357SAndroid Build Coastguard Worker   COPY_LZMA_ENC_STATE(p, v, p)
529*f6dc9357SAndroid Build Coastguard Worker }
530*f6dc9357SAndroid Build Coastguard Worker 
531*f6dc9357SAndroid Build Coastguard Worker 
532*f6dc9357SAndroid Build Coastguard Worker Z7_NO_INLINE
LzmaEnc_SetProps(CLzmaEncHandle p,const CLzmaEncProps * props2)533*f6dc9357SAndroid Build Coastguard Worker SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props2)
534*f6dc9357SAndroid Build Coastguard Worker {
535*f6dc9357SAndroid Build Coastguard Worker   // GET_CLzmaEnc_p
536*f6dc9357SAndroid Build Coastguard Worker   CLzmaEncProps props = *props2;
537*f6dc9357SAndroid Build Coastguard Worker   LzmaEncProps_Normalize(&props);
538*f6dc9357SAndroid Build Coastguard Worker 
539*f6dc9357SAndroid Build Coastguard Worker   if (props.lc > LZMA_LC_MAX
540*f6dc9357SAndroid Build Coastguard Worker       || props.lp > LZMA_LP_MAX
541*f6dc9357SAndroid Build Coastguard Worker       || props.pb > LZMA_PB_MAX)
542*f6dc9357SAndroid Build Coastguard Worker     return SZ_ERROR_PARAM;
543*f6dc9357SAndroid Build Coastguard Worker 
544*f6dc9357SAndroid Build Coastguard Worker 
545*f6dc9357SAndroid Build Coastguard Worker   if (props.dictSize > kLzmaMaxHistorySize)
546*f6dc9357SAndroid Build Coastguard Worker     props.dictSize = kLzmaMaxHistorySize;
547*f6dc9357SAndroid Build Coastguard Worker 
548*f6dc9357SAndroid Build Coastguard Worker   #ifndef LZMA_LOG_BSR
549*f6dc9357SAndroid Build Coastguard Worker   {
550*f6dc9357SAndroid Build Coastguard Worker     const UInt64 dict64 = props.dictSize;
551*f6dc9357SAndroid Build Coastguard Worker     if (dict64 > ((UInt64)1 << kDicLogSizeMaxCompress))
552*f6dc9357SAndroid Build Coastguard Worker       return SZ_ERROR_PARAM;
553*f6dc9357SAndroid Build Coastguard Worker   }
554*f6dc9357SAndroid Build Coastguard Worker   #endif
555*f6dc9357SAndroid Build Coastguard Worker 
556*f6dc9357SAndroid Build Coastguard Worker   p->dictSize = props.dictSize;
557*f6dc9357SAndroid Build Coastguard Worker   {
558*f6dc9357SAndroid Build Coastguard Worker     unsigned fb = (unsigned)props.fb;
559*f6dc9357SAndroid Build Coastguard Worker     if (fb < 5)
560*f6dc9357SAndroid Build Coastguard Worker       fb = 5;
561*f6dc9357SAndroid Build Coastguard Worker     if (fb > LZMA_MATCH_LEN_MAX)
562*f6dc9357SAndroid Build Coastguard Worker       fb = LZMA_MATCH_LEN_MAX;
563*f6dc9357SAndroid Build Coastguard Worker     p->numFastBytes = fb;
564*f6dc9357SAndroid Build Coastguard Worker   }
565*f6dc9357SAndroid Build Coastguard Worker   p->lc = (unsigned)props.lc;
566*f6dc9357SAndroid Build Coastguard Worker   p->lp = (unsigned)props.lp;
567*f6dc9357SAndroid Build Coastguard Worker   p->pb = (unsigned)props.pb;
568*f6dc9357SAndroid Build Coastguard Worker   p->fastMode = (props.algo == 0);
569*f6dc9357SAndroid Build Coastguard Worker   // p->_maxMode = True;
570*f6dc9357SAndroid Build Coastguard Worker   MFB.btMode = (Byte)(props.btMode ? 1 : 0);
571*f6dc9357SAndroid Build Coastguard Worker   // MFB.btMode = (Byte)(props.btMode);
572*f6dc9357SAndroid Build Coastguard Worker   {
573*f6dc9357SAndroid Build Coastguard Worker     unsigned numHashBytes = 4;
574*f6dc9357SAndroid Build Coastguard Worker     if (props.btMode)
575*f6dc9357SAndroid Build Coastguard Worker     {
576*f6dc9357SAndroid Build Coastguard Worker            if (props.numHashBytes <  2) numHashBytes = 2;
577*f6dc9357SAndroid Build Coastguard Worker       else if (props.numHashBytes <  4) numHashBytes = (unsigned)props.numHashBytes;
578*f6dc9357SAndroid Build Coastguard Worker     }
579*f6dc9357SAndroid Build Coastguard Worker     if (props.numHashBytes >= 5) numHashBytes = 5;
580*f6dc9357SAndroid Build Coastguard Worker 
581*f6dc9357SAndroid Build Coastguard Worker     MFB.numHashBytes = numHashBytes;
582*f6dc9357SAndroid Build Coastguard Worker     // MFB.numHashBytes_Min = 2;
583*f6dc9357SAndroid Build Coastguard Worker     MFB.numHashOutBits = (Byte)props.numHashOutBits;
584*f6dc9357SAndroid Build Coastguard Worker   }
585*f6dc9357SAndroid Build Coastguard Worker 
586*f6dc9357SAndroid Build Coastguard Worker   MFB.cutValue = props.mc;
587*f6dc9357SAndroid Build Coastguard Worker 
588*f6dc9357SAndroid Build Coastguard Worker   p->writeEndMark = (BoolInt)props.writeEndMark;
589*f6dc9357SAndroid Build Coastguard Worker 
590*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
591*f6dc9357SAndroid Build Coastguard Worker   /*
592*f6dc9357SAndroid Build Coastguard Worker   if (newMultiThread != _multiThread)
593*f6dc9357SAndroid Build Coastguard Worker   {
594*f6dc9357SAndroid Build Coastguard Worker     ReleaseMatchFinder();
595*f6dc9357SAndroid Build Coastguard Worker     _multiThread = newMultiThread;
596*f6dc9357SAndroid Build Coastguard Worker   }
597*f6dc9357SAndroid Build Coastguard Worker   */
598*f6dc9357SAndroid Build Coastguard Worker   p->multiThread = (props.numThreads > 1);
599*f6dc9357SAndroid Build Coastguard Worker   p->matchFinderMt.btSync.affinity =
600*f6dc9357SAndroid Build Coastguard Worker   p->matchFinderMt.hashSync.affinity = props.affinity;
601*f6dc9357SAndroid Build Coastguard Worker   #endif
602*f6dc9357SAndroid Build Coastguard Worker 
603*f6dc9357SAndroid Build Coastguard Worker   return SZ_OK;
604*f6dc9357SAndroid Build Coastguard Worker }
605*f6dc9357SAndroid Build Coastguard Worker 
606*f6dc9357SAndroid Build Coastguard Worker 
LzmaEnc_SetDataSize(CLzmaEncHandle p,UInt64 expectedDataSiize)607*f6dc9357SAndroid Build Coastguard Worker void LzmaEnc_SetDataSize(CLzmaEncHandle p, UInt64 expectedDataSiize)
608*f6dc9357SAndroid Build Coastguard Worker {
609*f6dc9357SAndroid Build Coastguard Worker   // GET_CLzmaEnc_p
610*f6dc9357SAndroid Build Coastguard Worker   MFB.expectedDataSize = expectedDataSiize;
611*f6dc9357SAndroid Build Coastguard Worker }
612*f6dc9357SAndroid Build Coastguard Worker 
613*f6dc9357SAndroid Build Coastguard Worker 
614*f6dc9357SAndroid Build Coastguard Worker #define kState_Start 0
615*f6dc9357SAndroid Build Coastguard Worker #define kState_LitAfterMatch 4
616*f6dc9357SAndroid Build Coastguard Worker #define kState_LitAfterRep   5
617*f6dc9357SAndroid Build Coastguard Worker #define kState_MatchAfterLit 7
618*f6dc9357SAndroid Build Coastguard Worker #define kState_RepAfterLit   8
619*f6dc9357SAndroid Build Coastguard Worker 
620*f6dc9357SAndroid Build Coastguard Worker static const Byte kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4,  5,  6,   4, 5};
621*f6dc9357SAndroid Build Coastguard Worker static const Byte kMatchNextStates[kNumStates]   = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
622*f6dc9357SAndroid Build Coastguard Worker static const Byte kRepNextStates[kNumStates]     = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
623*f6dc9357SAndroid Build Coastguard Worker static const Byte kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
624*f6dc9357SAndroid Build Coastguard Worker 
625*f6dc9357SAndroid Build Coastguard Worker #define IsLitState(s) ((s) < 7)
626*f6dc9357SAndroid Build Coastguard Worker #define GetLenToPosState2(len) (((len) < kNumLenToPosStates - 1) ? (len) : kNumLenToPosStates - 1)
627*f6dc9357SAndroid Build Coastguard Worker #define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1)
628*f6dc9357SAndroid Build Coastguard Worker 
629*f6dc9357SAndroid Build Coastguard Worker #define kInfinityPrice (1 << 30)
630*f6dc9357SAndroid Build Coastguard Worker 
RangeEnc_Construct(CRangeEnc * p)631*f6dc9357SAndroid Build Coastguard Worker static void RangeEnc_Construct(CRangeEnc *p)
632*f6dc9357SAndroid Build Coastguard Worker {
633*f6dc9357SAndroid Build Coastguard Worker   p->outStream = NULL;
634*f6dc9357SAndroid Build Coastguard Worker   p->bufBase = NULL;
635*f6dc9357SAndroid Build Coastguard Worker }
636*f6dc9357SAndroid Build Coastguard Worker 
637*f6dc9357SAndroid Build Coastguard Worker #define RangeEnc_GetProcessed(p)       (        (p)->processed + (size_t)((p)->buf - (p)->bufBase) +         (p)->cacheSize)
638*f6dc9357SAndroid Build Coastguard Worker #define RangeEnc_GetProcessed_sizet(p) ((size_t)(p)->processed + (size_t)((p)->buf - (p)->bufBase) + (size_t)(p)->cacheSize)
639*f6dc9357SAndroid Build Coastguard Worker 
640*f6dc9357SAndroid Build Coastguard Worker #define RC_BUF_SIZE (1 << 16)
641*f6dc9357SAndroid Build Coastguard Worker 
RangeEnc_Alloc(CRangeEnc * p,ISzAllocPtr alloc)642*f6dc9357SAndroid Build Coastguard Worker static int RangeEnc_Alloc(CRangeEnc *p, ISzAllocPtr alloc)
643*f6dc9357SAndroid Build Coastguard Worker {
644*f6dc9357SAndroid Build Coastguard Worker   if (!p->bufBase)
645*f6dc9357SAndroid Build Coastguard Worker   {
646*f6dc9357SAndroid Build Coastguard Worker     p->bufBase = (Byte *)ISzAlloc_Alloc(alloc, RC_BUF_SIZE);
647*f6dc9357SAndroid Build Coastguard Worker     if (!p->bufBase)
648*f6dc9357SAndroid Build Coastguard Worker       return 0;
649*f6dc9357SAndroid Build Coastguard Worker     p->bufLim = p->bufBase + RC_BUF_SIZE;
650*f6dc9357SAndroid Build Coastguard Worker   }
651*f6dc9357SAndroid Build Coastguard Worker   return 1;
652*f6dc9357SAndroid Build Coastguard Worker }
653*f6dc9357SAndroid Build Coastguard Worker 
RangeEnc_Free(CRangeEnc * p,ISzAllocPtr alloc)654*f6dc9357SAndroid Build Coastguard Worker static void RangeEnc_Free(CRangeEnc *p, ISzAllocPtr alloc)
655*f6dc9357SAndroid Build Coastguard Worker {
656*f6dc9357SAndroid Build Coastguard Worker   ISzAlloc_Free(alloc, p->bufBase);
657*f6dc9357SAndroid Build Coastguard Worker   p->bufBase = NULL;
658*f6dc9357SAndroid Build Coastguard Worker }
659*f6dc9357SAndroid Build Coastguard Worker 
RangeEnc_Init(CRangeEnc * p)660*f6dc9357SAndroid Build Coastguard Worker static void RangeEnc_Init(CRangeEnc *p)
661*f6dc9357SAndroid Build Coastguard Worker {
662*f6dc9357SAndroid Build Coastguard Worker   p->range = 0xFFFFFFFF;
663*f6dc9357SAndroid Build Coastguard Worker   p->cache = 0;
664*f6dc9357SAndroid Build Coastguard Worker   p->low = 0;
665*f6dc9357SAndroid Build Coastguard Worker   p->cacheSize = 0;
666*f6dc9357SAndroid Build Coastguard Worker 
667*f6dc9357SAndroid Build Coastguard Worker   p->buf = p->bufBase;
668*f6dc9357SAndroid Build Coastguard Worker 
669*f6dc9357SAndroid Build Coastguard Worker   p->processed = 0;
670*f6dc9357SAndroid Build Coastguard Worker   p->res = SZ_OK;
671*f6dc9357SAndroid Build Coastguard Worker }
672*f6dc9357SAndroid Build Coastguard Worker 
RangeEnc_FlushStream(CRangeEnc * p)673*f6dc9357SAndroid Build Coastguard Worker Z7_NO_INLINE static void RangeEnc_FlushStream(CRangeEnc *p)
674*f6dc9357SAndroid Build Coastguard Worker {
675*f6dc9357SAndroid Build Coastguard Worker   const size_t num = (size_t)(p->buf - p->bufBase);
676*f6dc9357SAndroid Build Coastguard Worker   if (p->res == SZ_OK)
677*f6dc9357SAndroid Build Coastguard Worker   {
678*f6dc9357SAndroid Build Coastguard Worker     if (num != ISeqOutStream_Write(p->outStream, p->bufBase, num))
679*f6dc9357SAndroid Build Coastguard Worker       p->res = SZ_ERROR_WRITE;
680*f6dc9357SAndroid Build Coastguard Worker   }
681*f6dc9357SAndroid Build Coastguard Worker   p->processed += num;
682*f6dc9357SAndroid Build Coastguard Worker   p->buf = p->bufBase;
683*f6dc9357SAndroid Build Coastguard Worker }
684*f6dc9357SAndroid Build Coastguard Worker 
RangeEnc_ShiftLow(CRangeEnc * p)685*f6dc9357SAndroid Build Coastguard Worker Z7_NO_INLINE static void Z7_FASTCALL RangeEnc_ShiftLow(CRangeEnc *p)
686*f6dc9357SAndroid Build Coastguard Worker {
687*f6dc9357SAndroid Build Coastguard Worker   UInt32 low = (UInt32)p->low;
688*f6dc9357SAndroid Build Coastguard Worker   unsigned high = (unsigned)(p->low >> 32);
689*f6dc9357SAndroid Build Coastguard Worker   p->low = (UInt32)(low << 8);
690*f6dc9357SAndroid Build Coastguard Worker   if (low < (UInt32)0xFF000000 || high != 0)
691*f6dc9357SAndroid Build Coastguard Worker   {
692*f6dc9357SAndroid Build Coastguard Worker     {
693*f6dc9357SAndroid Build Coastguard Worker       Byte *buf = p->buf;
694*f6dc9357SAndroid Build Coastguard Worker       *buf++ = (Byte)(p->cache + high);
695*f6dc9357SAndroid Build Coastguard Worker       p->cache = (unsigned)(low >> 24);
696*f6dc9357SAndroid Build Coastguard Worker       p->buf = buf;
697*f6dc9357SAndroid Build Coastguard Worker       if (buf == p->bufLim)
698*f6dc9357SAndroid Build Coastguard Worker         RangeEnc_FlushStream(p);
699*f6dc9357SAndroid Build Coastguard Worker       if (p->cacheSize == 0)
700*f6dc9357SAndroid Build Coastguard Worker         return;
701*f6dc9357SAndroid Build Coastguard Worker     }
702*f6dc9357SAndroid Build Coastguard Worker     high += 0xFF;
703*f6dc9357SAndroid Build Coastguard Worker     for (;;)
704*f6dc9357SAndroid Build Coastguard Worker     {
705*f6dc9357SAndroid Build Coastguard Worker       Byte *buf = p->buf;
706*f6dc9357SAndroid Build Coastguard Worker       *buf++ = (Byte)(high);
707*f6dc9357SAndroid Build Coastguard Worker       p->buf = buf;
708*f6dc9357SAndroid Build Coastguard Worker       if (buf == p->bufLim)
709*f6dc9357SAndroid Build Coastguard Worker         RangeEnc_FlushStream(p);
710*f6dc9357SAndroid Build Coastguard Worker       if (--p->cacheSize == 0)
711*f6dc9357SAndroid Build Coastguard Worker         return;
712*f6dc9357SAndroid Build Coastguard Worker     }
713*f6dc9357SAndroid Build Coastguard Worker   }
714*f6dc9357SAndroid Build Coastguard Worker   p->cacheSize++;
715*f6dc9357SAndroid Build Coastguard Worker }
716*f6dc9357SAndroid Build Coastguard Worker 
RangeEnc_FlushData(CRangeEnc * p)717*f6dc9357SAndroid Build Coastguard Worker static void RangeEnc_FlushData(CRangeEnc *p)
718*f6dc9357SAndroid Build Coastguard Worker {
719*f6dc9357SAndroid Build Coastguard Worker   int i;
720*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < 5; i++)
721*f6dc9357SAndroid Build Coastguard Worker     RangeEnc_ShiftLow(p);
722*f6dc9357SAndroid Build Coastguard Worker }
723*f6dc9357SAndroid Build Coastguard Worker 
724*f6dc9357SAndroid Build Coastguard Worker #define RC_NORM(p) if (range < kTopValue) { range <<= 8; RangeEnc_ShiftLow(p); }
725*f6dc9357SAndroid Build Coastguard Worker 
726*f6dc9357SAndroid Build Coastguard Worker #define RC_BIT_PRE(p, prob) \
727*f6dc9357SAndroid Build Coastguard Worker   ttt = *(prob); \
728*f6dc9357SAndroid Build Coastguard Worker   newBound = (range >> kNumBitModelTotalBits) * ttt;
729*f6dc9357SAndroid Build Coastguard Worker 
730*f6dc9357SAndroid Build Coastguard Worker // #define Z7_LZMA_ENC_USE_BRANCH
731*f6dc9357SAndroid Build Coastguard Worker 
732*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_LZMA_ENC_USE_BRANCH
733*f6dc9357SAndroid Build Coastguard Worker 
734*f6dc9357SAndroid Build Coastguard Worker #define RC_BIT(p, prob, bit) { \
735*f6dc9357SAndroid Build Coastguard Worker   RC_BIT_PRE(p, prob) \
736*f6dc9357SAndroid Build Coastguard Worker   if (bit == 0) { range = newBound; ttt += (kBitModelTotal - ttt) >> kNumMoveBits; } \
737*f6dc9357SAndroid Build Coastguard Worker   else { (p)->low += newBound; range -= newBound; ttt -= ttt >> kNumMoveBits; } \
738*f6dc9357SAndroid Build Coastguard Worker   *(prob) = (CLzmaProb)ttt; \
739*f6dc9357SAndroid Build Coastguard Worker   RC_NORM(p) \
740*f6dc9357SAndroid Build Coastguard Worker   }
741*f6dc9357SAndroid Build Coastguard Worker 
742*f6dc9357SAndroid Build Coastguard Worker #else
743*f6dc9357SAndroid Build Coastguard Worker 
744*f6dc9357SAndroid Build Coastguard Worker #define RC_BIT(p, prob, bit) { \
745*f6dc9357SAndroid Build Coastguard Worker   UInt32 mask; \
746*f6dc9357SAndroid Build Coastguard Worker   RC_BIT_PRE(p, prob) \
747*f6dc9357SAndroid Build Coastguard Worker   mask = 0 - (UInt32)bit; \
748*f6dc9357SAndroid Build Coastguard Worker   range &= mask; \
749*f6dc9357SAndroid Build Coastguard Worker   mask &= newBound; \
750*f6dc9357SAndroid Build Coastguard Worker   range -= mask; \
751*f6dc9357SAndroid Build Coastguard Worker   (p)->low += mask; \
752*f6dc9357SAndroid Build Coastguard Worker   mask = (UInt32)bit - 1; \
753*f6dc9357SAndroid Build Coastguard Worker   range += newBound & mask; \
754*f6dc9357SAndroid Build Coastguard Worker   mask &= (kBitModelTotal - ((1 << kNumMoveBits) - 1)); \
755*f6dc9357SAndroid Build Coastguard Worker   mask += ((1 << kNumMoveBits) - 1); \
756*f6dc9357SAndroid Build Coastguard Worker   ttt += (UInt32)((Int32)(mask - ttt) >> kNumMoveBits); \
757*f6dc9357SAndroid Build Coastguard Worker   *(prob) = (CLzmaProb)ttt; \
758*f6dc9357SAndroid Build Coastguard Worker   RC_NORM(p) \
759*f6dc9357SAndroid Build Coastguard Worker   }
760*f6dc9357SAndroid Build Coastguard Worker 
761*f6dc9357SAndroid Build Coastguard Worker #endif
762*f6dc9357SAndroid Build Coastguard Worker 
763*f6dc9357SAndroid Build Coastguard Worker 
764*f6dc9357SAndroid Build Coastguard Worker 
765*f6dc9357SAndroid Build Coastguard Worker 
766*f6dc9357SAndroid Build Coastguard Worker #define RC_BIT_0_BASE(p, prob) \
767*f6dc9357SAndroid Build Coastguard Worker   range = newBound; *(prob) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
768*f6dc9357SAndroid Build Coastguard Worker 
769*f6dc9357SAndroid Build Coastguard Worker #define RC_BIT_1_BASE(p, prob) \
770*f6dc9357SAndroid Build Coastguard Worker   range -= newBound; (p)->low += newBound; *(prob) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); \
771*f6dc9357SAndroid Build Coastguard Worker 
772*f6dc9357SAndroid Build Coastguard Worker #define RC_BIT_0(p, prob) \
773*f6dc9357SAndroid Build Coastguard Worker   RC_BIT_0_BASE(p, prob) \
774*f6dc9357SAndroid Build Coastguard Worker   RC_NORM(p)
775*f6dc9357SAndroid Build Coastguard Worker 
776*f6dc9357SAndroid Build Coastguard Worker #define RC_BIT_1(p, prob) \
777*f6dc9357SAndroid Build Coastguard Worker   RC_BIT_1_BASE(p, prob) \
778*f6dc9357SAndroid Build Coastguard Worker   RC_NORM(p)
779*f6dc9357SAndroid Build Coastguard Worker 
RangeEnc_EncodeBit_0(CRangeEnc * p,CLzmaProb * prob)780*f6dc9357SAndroid Build Coastguard Worker static void RangeEnc_EncodeBit_0(CRangeEnc *p, CLzmaProb *prob)
781*f6dc9357SAndroid Build Coastguard Worker {
782*f6dc9357SAndroid Build Coastguard Worker   UInt32 range, ttt, newBound;
783*f6dc9357SAndroid Build Coastguard Worker   range = p->range;
784*f6dc9357SAndroid Build Coastguard Worker   RC_BIT_PRE(p, prob)
785*f6dc9357SAndroid Build Coastguard Worker   RC_BIT_0(p, prob)
786*f6dc9357SAndroid Build Coastguard Worker   p->range = range;
787*f6dc9357SAndroid Build Coastguard Worker }
788*f6dc9357SAndroid Build Coastguard Worker 
LitEnc_Encode(CRangeEnc * p,CLzmaProb * probs,UInt32 sym)789*f6dc9357SAndroid Build Coastguard Worker static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 sym)
790*f6dc9357SAndroid Build Coastguard Worker {
791*f6dc9357SAndroid Build Coastguard Worker   UInt32 range = p->range;
792*f6dc9357SAndroid Build Coastguard Worker   sym |= 0x100;
793*f6dc9357SAndroid Build Coastguard Worker   do
794*f6dc9357SAndroid Build Coastguard Worker   {
795*f6dc9357SAndroid Build Coastguard Worker     UInt32 ttt, newBound;
796*f6dc9357SAndroid Build Coastguard Worker     // RangeEnc_EncodeBit(p, probs + (sym >> 8), (sym >> 7) & 1);
797*f6dc9357SAndroid Build Coastguard Worker     CLzmaProb *prob = probs + (sym >> 8);
798*f6dc9357SAndroid Build Coastguard Worker     UInt32 bit = (sym >> 7) & 1;
799*f6dc9357SAndroid Build Coastguard Worker     sym <<= 1;
800*f6dc9357SAndroid Build Coastguard Worker     RC_BIT(p, prob, bit)
801*f6dc9357SAndroid Build Coastguard Worker   }
802*f6dc9357SAndroid Build Coastguard Worker   while (sym < 0x10000);
803*f6dc9357SAndroid Build Coastguard Worker   p->range = range;
804*f6dc9357SAndroid Build Coastguard Worker }
805*f6dc9357SAndroid Build Coastguard Worker 
LitEnc_EncodeMatched(CRangeEnc * p,CLzmaProb * probs,UInt32 sym,UInt32 matchByte)806*f6dc9357SAndroid Build Coastguard Worker static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 sym, UInt32 matchByte)
807*f6dc9357SAndroid Build Coastguard Worker {
808*f6dc9357SAndroid Build Coastguard Worker   UInt32 range = p->range;
809*f6dc9357SAndroid Build Coastguard Worker   UInt32 offs = 0x100;
810*f6dc9357SAndroid Build Coastguard Worker   sym |= 0x100;
811*f6dc9357SAndroid Build Coastguard Worker   do
812*f6dc9357SAndroid Build Coastguard Worker   {
813*f6dc9357SAndroid Build Coastguard Worker     UInt32 ttt, newBound;
814*f6dc9357SAndroid Build Coastguard Worker     CLzmaProb *prob;
815*f6dc9357SAndroid Build Coastguard Worker     UInt32 bit;
816*f6dc9357SAndroid Build Coastguard Worker     matchByte <<= 1;
817*f6dc9357SAndroid Build Coastguard Worker     // RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (sym >> 8)), (sym >> 7) & 1);
818*f6dc9357SAndroid Build Coastguard Worker     prob = probs + (offs + (matchByte & offs) + (sym >> 8));
819*f6dc9357SAndroid Build Coastguard Worker     bit = (sym >> 7) & 1;
820*f6dc9357SAndroid Build Coastguard Worker     sym <<= 1;
821*f6dc9357SAndroid Build Coastguard Worker     offs &= ~(matchByte ^ sym);
822*f6dc9357SAndroid Build Coastguard Worker     RC_BIT(p, prob, bit)
823*f6dc9357SAndroid Build Coastguard Worker   }
824*f6dc9357SAndroid Build Coastguard Worker   while (sym < 0x10000);
825*f6dc9357SAndroid Build Coastguard Worker   p->range = range;
826*f6dc9357SAndroid Build Coastguard Worker }
827*f6dc9357SAndroid Build Coastguard Worker 
828*f6dc9357SAndroid Build Coastguard Worker 
829*f6dc9357SAndroid Build Coastguard Worker 
LzmaEnc_InitPriceTables(CProbPrice * ProbPrices)830*f6dc9357SAndroid Build Coastguard Worker static void LzmaEnc_InitPriceTables(CProbPrice *ProbPrices)
831*f6dc9357SAndroid Build Coastguard Worker {
832*f6dc9357SAndroid Build Coastguard Worker   UInt32 i;
833*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < (kBitModelTotal >> kNumMoveReducingBits); i++)
834*f6dc9357SAndroid Build Coastguard Worker   {
835*f6dc9357SAndroid Build Coastguard Worker     const unsigned kCyclesBits = kNumBitPriceShiftBits;
836*f6dc9357SAndroid Build Coastguard Worker     UInt32 w = (i << kNumMoveReducingBits) + (1 << (kNumMoveReducingBits - 1));
837*f6dc9357SAndroid Build Coastguard Worker     unsigned bitCount = 0;
838*f6dc9357SAndroid Build Coastguard Worker     unsigned j;
839*f6dc9357SAndroid Build Coastguard Worker     for (j = 0; j < kCyclesBits; j++)
840*f6dc9357SAndroid Build Coastguard Worker     {
841*f6dc9357SAndroid Build Coastguard Worker       w = w * w;
842*f6dc9357SAndroid Build Coastguard Worker       bitCount <<= 1;
843*f6dc9357SAndroid Build Coastguard Worker       while (w >= ((UInt32)1 << 16))
844*f6dc9357SAndroid Build Coastguard Worker       {
845*f6dc9357SAndroid Build Coastguard Worker         w >>= 1;
846*f6dc9357SAndroid Build Coastguard Worker         bitCount++;
847*f6dc9357SAndroid Build Coastguard Worker       }
848*f6dc9357SAndroid Build Coastguard Worker     }
849*f6dc9357SAndroid Build Coastguard Worker     ProbPrices[i] = (CProbPrice)(((unsigned)kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount);
850*f6dc9357SAndroid Build Coastguard Worker     // printf("\n%3d: %5d", i, ProbPrices[i]);
851*f6dc9357SAndroid Build Coastguard Worker   }
852*f6dc9357SAndroid Build Coastguard Worker }
853*f6dc9357SAndroid Build Coastguard Worker 
854*f6dc9357SAndroid Build Coastguard Worker 
855*f6dc9357SAndroid Build Coastguard Worker #define GET_PRICE(prob, bit) \
856*f6dc9357SAndroid Build Coastguard Worker   p->ProbPrices[((prob) ^ (unsigned)(((-(int)(bit))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]
857*f6dc9357SAndroid Build Coastguard Worker 
858*f6dc9357SAndroid Build Coastguard Worker #define GET_PRICEa(prob, bit) \
859*f6dc9357SAndroid Build Coastguard Worker      ProbPrices[((prob) ^ (unsigned)((-((int)(bit))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]
860*f6dc9357SAndroid Build Coastguard Worker 
861*f6dc9357SAndroid Build Coastguard Worker #define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits]
862*f6dc9357SAndroid Build Coastguard Worker #define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
863*f6dc9357SAndroid Build Coastguard Worker 
864*f6dc9357SAndroid Build Coastguard Worker #define GET_PRICEa_0(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
865*f6dc9357SAndroid Build Coastguard Worker #define GET_PRICEa_1(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
866*f6dc9357SAndroid Build Coastguard Worker 
867*f6dc9357SAndroid Build Coastguard Worker 
LitEnc_GetPrice(const CLzmaProb * probs,UInt32 sym,const CProbPrice * ProbPrices)868*f6dc9357SAndroid Build Coastguard Worker static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 sym, const CProbPrice *ProbPrices)
869*f6dc9357SAndroid Build Coastguard Worker {
870*f6dc9357SAndroid Build Coastguard Worker   UInt32 price = 0;
871*f6dc9357SAndroid Build Coastguard Worker   sym |= 0x100;
872*f6dc9357SAndroid Build Coastguard Worker   do
873*f6dc9357SAndroid Build Coastguard Worker   {
874*f6dc9357SAndroid Build Coastguard Worker     unsigned bit = sym & 1;
875*f6dc9357SAndroid Build Coastguard Worker     sym >>= 1;
876*f6dc9357SAndroid Build Coastguard Worker     price += GET_PRICEa(probs[sym], bit);
877*f6dc9357SAndroid Build Coastguard Worker   }
878*f6dc9357SAndroid Build Coastguard Worker   while (sym >= 2);
879*f6dc9357SAndroid Build Coastguard Worker   return price;
880*f6dc9357SAndroid Build Coastguard Worker }
881*f6dc9357SAndroid Build Coastguard Worker 
882*f6dc9357SAndroid Build Coastguard Worker 
LitEnc_Matched_GetPrice(const CLzmaProb * probs,UInt32 sym,UInt32 matchByte,const CProbPrice * ProbPrices)883*f6dc9357SAndroid Build Coastguard Worker static UInt32 LitEnc_Matched_GetPrice(const CLzmaProb *probs, UInt32 sym, UInt32 matchByte, const CProbPrice *ProbPrices)
884*f6dc9357SAndroid Build Coastguard Worker {
885*f6dc9357SAndroid Build Coastguard Worker   UInt32 price = 0;
886*f6dc9357SAndroid Build Coastguard Worker   UInt32 offs = 0x100;
887*f6dc9357SAndroid Build Coastguard Worker   sym |= 0x100;
888*f6dc9357SAndroid Build Coastguard Worker   do
889*f6dc9357SAndroid Build Coastguard Worker   {
890*f6dc9357SAndroid Build Coastguard Worker     matchByte <<= 1;
891*f6dc9357SAndroid Build Coastguard Worker     price += GET_PRICEa(probs[offs + (matchByte & offs) + (sym >> 8)], (sym >> 7) & 1);
892*f6dc9357SAndroid Build Coastguard Worker     sym <<= 1;
893*f6dc9357SAndroid Build Coastguard Worker     offs &= ~(matchByte ^ sym);
894*f6dc9357SAndroid Build Coastguard Worker   }
895*f6dc9357SAndroid Build Coastguard Worker   while (sym < 0x10000);
896*f6dc9357SAndroid Build Coastguard Worker   return price;
897*f6dc9357SAndroid Build Coastguard Worker }
898*f6dc9357SAndroid Build Coastguard Worker 
899*f6dc9357SAndroid Build Coastguard Worker 
RcTree_ReverseEncode(CRangeEnc * rc,CLzmaProb * probs,unsigned numBits,unsigned sym)900*f6dc9357SAndroid Build Coastguard Worker static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, unsigned numBits, unsigned sym)
901*f6dc9357SAndroid Build Coastguard Worker {
902*f6dc9357SAndroid Build Coastguard Worker   UInt32 range = rc->range;
903*f6dc9357SAndroid Build Coastguard Worker   unsigned m = 1;
904*f6dc9357SAndroid Build Coastguard Worker   do
905*f6dc9357SAndroid Build Coastguard Worker   {
906*f6dc9357SAndroid Build Coastguard Worker     UInt32 ttt, newBound;
907*f6dc9357SAndroid Build Coastguard Worker     unsigned bit = sym & 1;
908*f6dc9357SAndroid Build Coastguard Worker     // RangeEnc_EncodeBit(rc, probs + m, bit);
909*f6dc9357SAndroid Build Coastguard Worker     sym >>= 1;
910*f6dc9357SAndroid Build Coastguard Worker     RC_BIT(rc, probs + m, bit)
911*f6dc9357SAndroid Build Coastguard Worker     m = (m << 1) | bit;
912*f6dc9357SAndroid Build Coastguard Worker   }
913*f6dc9357SAndroid Build Coastguard Worker   while (--numBits);
914*f6dc9357SAndroid Build Coastguard Worker   rc->range = range;
915*f6dc9357SAndroid Build Coastguard Worker }
916*f6dc9357SAndroid Build Coastguard Worker 
917*f6dc9357SAndroid Build Coastguard Worker 
918*f6dc9357SAndroid Build Coastguard Worker 
LenEnc_Init(CLenEnc * p)919*f6dc9357SAndroid Build Coastguard Worker static void LenEnc_Init(CLenEnc *p)
920*f6dc9357SAndroid Build Coastguard Worker {
921*f6dc9357SAndroid Build Coastguard Worker   unsigned i;
922*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << (kLenNumLowBits + 1)); i++)
923*f6dc9357SAndroid Build Coastguard Worker     p->low[i] = kProbInitValue;
924*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < kLenNumHighSymbols; i++)
925*f6dc9357SAndroid Build Coastguard Worker     p->high[i] = kProbInitValue;
926*f6dc9357SAndroid Build Coastguard Worker }
927*f6dc9357SAndroid Build Coastguard Worker 
LenEnc_Encode(CLenEnc * p,CRangeEnc * rc,unsigned sym,unsigned posState)928*f6dc9357SAndroid Build Coastguard Worker static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, unsigned sym, unsigned posState)
929*f6dc9357SAndroid Build Coastguard Worker {
930*f6dc9357SAndroid Build Coastguard Worker   UInt32 range, ttt, newBound;
931*f6dc9357SAndroid Build Coastguard Worker   CLzmaProb *probs = p->low;
932*f6dc9357SAndroid Build Coastguard Worker   range = rc->range;
933*f6dc9357SAndroid Build Coastguard Worker   RC_BIT_PRE(rc, probs)
934*f6dc9357SAndroid Build Coastguard Worker   if (sym >= kLenNumLowSymbols)
935*f6dc9357SAndroid Build Coastguard Worker   {
936*f6dc9357SAndroid Build Coastguard Worker     RC_BIT_1(rc, probs)
937*f6dc9357SAndroid Build Coastguard Worker     probs += kLenNumLowSymbols;
938*f6dc9357SAndroid Build Coastguard Worker     RC_BIT_PRE(rc, probs)
939*f6dc9357SAndroid Build Coastguard Worker     if (sym >= kLenNumLowSymbols * 2)
940*f6dc9357SAndroid Build Coastguard Worker     {
941*f6dc9357SAndroid Build Coastguard Worker       RC_BIT_1(rc, probs)
942*f6dc9357SAndroid Build Coastguard Worker       rc->range = range;
943*f6dc9357SAndroid Build Coastguard Worker       // RcTree_Encode(rc, p->high, kLenNumHighBits, sym - kLenNumLowSymbols * 2);
944*f6dc9357SAndroid Build Coastguard Worker       LitEnc_Encode(rc, p->high, sym - kLenNumLowSymbols * 2);
945*f6dc9357SAndroid Build Coastguard Worker       return;
946*f6dc9357SAndroid Build Coastguard Worker     }
947*f6dc9357SAndroid Build Coastguard Worker     sym -= kLenNumLowSymbols;
948*f6dc9357SAndroid Build Coastguard Worker   }
949*f6dc9357SAndroid Build Coastguard Worker 
950*f6dc9357SAndroid Build Coastguard Worker   // RcTree_Encode(rc, probs + (posState << kLenNumLowBits), kLenNumLowBits, sym);
951*f6dc9357SAndroid Build Coastguard Worker   {
952*f6dc9357SAndroid Build Coastguard Worker     unsigned m;
953*f6dc9357SAndroid Build Coastguard Worker     unsigned bit;
954*f6dc9357SAndroid Build Coastguard Worker     RC_BIT_0(rc, probs)
955*f6dc9357SAndroid Build Coastguard Worker     probs += (posState << (1 + kLenNumLowBits));
956*f6dc9357SAndroid Build Coastguard Worker     bit = (sym >> 2)    ; RC_BIT(rc, probs + 1, bit)  m = (1 << 1) + bit;
957*f6dc9357SAndroid Build Coastguard Worker     bit = (sym >> 1) & 1; RC_BIT(rc, probs + m, bit)  m = (m << 1) + bit;
958*f6dc9357SAndroid Build Coastguard Worker     bit =  sym       & 1; RC_BIT(rc, probs + m, bit)
959*f6dc9357SAndroid Build Coastguard Worker     rc->range = range;
960*f6dc9357SAndroid Build Coastguard Worker   }
961*f6dc9357SAndroid Build Coastguard Worker }
962*f6dc9357SAndroid Build Coastguard Worker 
SetPrices_3(const CLzmaProb * probs,UInt32 startPrice,UInt32 * prices,const CProbPrice * ProbPrices)963*f6dc9357SAndroid Build Coastguard Worker static void SetPrices_3(const CLzmaProb *probs, UInt32 startPrice, UInt32 *prices, const CProbPrice *ProbPrices)
964*f6dc9357SAndroid Build Coastguard Worker {
965*f6dc9357SAndroid Build Coastguard Worker   unsigned i;
966*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < 8; i += 2)
967*f6dc9357SAndroid Build Coastguard Worker   {
968*f6dc9357SAndroid Build Coastguard Worker     UInt32 price = startPrice;
969*f6dc9357SAndroid Build Coastguard Worker     UInt32 prob;
970*f6dc9357SAndroid Build Coastguard Worker     price += GET_PRICEa(probs[1           ], (i >> 2));
971*f6dc9357SAndroid Build Coastguard Worker     price += GET_PRICEa(probs[2 + (i >> 2)], (i >> 1) & 1);
972*f6dc9357SAndroid Build Coastguard Worker     prob = probs[4 + (i >> 1)];
973*f6dc9357SAndroid Build Coastguard Worker     prices[i    ] = price + GET_PRICEa_0(prob);
974*f6dc9357SAndroid Build Coastguard Worker     prices[i + 1] = price + GET_PRICEa_1(prob);
975*f6dc9357SAndroid Build Coastguard Worker   }
976*f6dc9357SAndroid Build Coastguard Worker }
977*f6dc9357SAndroid Build Coastguard Worker 
978*f6dc9357SAndroid Build Coastguard Worker 
LenPriceEnc_UpdateTables(CLenPriceEnc * p,unsigned numPosStates,const CLenEnc * enc,const CProbPrice * ProbPrices)979*f6dc9357SAndroid Build Coastguard Worker Z7_NO_INLINE static void Z7_FASTCALL LenPriceEnc_UpdateTables(
980*f6dc9357SAndroid Build Coastguard Worker     CLenPriceEnc *p,
981*f6dc9357SAndroid Build Coastguard Worker     unsigned numPosStates,
982*f6dc9357SAndroid Build Coastguard Worker     const CLenEnc *enc,
983*f6dc9357SAndroid Build Coastguard Worker     const CProbPrice *ProbPrices)
984*f6dc9357SAndroid Build Coastguard Worker {
985*f6dc9357SAndroid Build Coastguard Worker   UInt32 b;
986*f6dc9357SAndroid Build Coastguard Worker 
987*f6dc9357SAndroid Build Coastguard Worker   {
988*f6dc9357SAndroid Build Coastguard Worker     unsigned prob = enc->low[0];
989*f6dc9357SAndroid Build Coastguard Worker     UInt32 a, c;
990*f6dc9357SAndroid Build Coastguard Worker     unsigned posState;
991*f6dc9357SAndroid Build Coastguard Worker     b = GET_PRICEa_1(prob);
992*f6dc9357SAndroid Build Coastguard Worker     a = GET_PRICEa_0(prob);
993*f6dc9357SAndroid Build Coastguard Worker     c = b + GET_PRICEa_0(enc->low[kLenNumLowSymbols]);
994*f6dc9357SAndroid Build Coastguard Worker     for (posState = 0; posState < numPosStates; posState++)
995*f6dc9357SAndroid Build Coastguard Worker     {
996*f6dc9357SAndroid Build Coastguard Worker       UInt32 *prices = p->prices[posState];
997*f6dc9357SAndroid Build Coastguard Worker       const CLzmaProb *probs = enc->low + (posState << (1 + kLenNumLowBits));
998*f6dc9357SAndroid Build Coastguard Worker       SetPrices_3(probs, a, prices, ProbPrices);
999*f6dc9357SAndroid Build Coastguard Worker       SetPrices_3(probs + kLenNumLowSymbols, c, prices + kLenNumLowSymbols, ProbPrices);
1000*f6dc9357SAndroid Build Coastguard Worker     }
1001*f6dc9357SAndroid Build Coastguard Worker   }
1002*f6dc9357SAndroid Build Coastguard Worker 
1003*f6dc9357SAndroid Build Coastguard Worker   /*
1004*f6dc9357SAndroid Build Coastguard Worker   {
1005*f6dc9357SAndroid Build Coastguard Worker     unsigned i;
1006*f6dc9357SAndroid Build Coastguard Worker     UInt32 b;
1007*f6dc9357SAndroid Build Coastguard Worker     a = GET_PRICEa_0(enc->low[0]);
1008*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < kLenNumLowSymbols; i++)
1009*f6dc9357SAndroid Build Coastguard Worker       p->prices2[i] = a;
1010*f6dc9357SAndroid Build Coastguard Worker     a = GET_PRICEa_1(enc->low[0]);
1011*f6dc9357SAndroid Build Coastguard Worker     b = a + GET_PRICEa_0(enc->low[kLenNumLowSymbols]);
1012*f6dc9357SAndroid Build Coastguard Worker     for (i = kLenNumLowSymbols; i < kLenNumLowSymbols * 2; i++)
1013*f6dc9357SAndroid Build Coastguard Worker       p->prices2[i] = b;
1014*f6dc9357SAndroid Build Coastguard Worker     a += GET_PRICEa_1(enc->low[kLenNumLowSymbols]);
1015*f6dc9357SAndroid Build Coastguard Worker   }
1016*f6dc9357SAndroid Build Coastguard Worker   */
1017*f6dc9357SAndroid Build Coastguard Worker 
1018*f6dc9357SAndroid Build Coastguard Worker   // p->counter = numSymbols;
1019*f6dc9357SAndroid Build Coastguard Worker   // p->counter = 64;
1020*f6dc9357SAndroid Build Coastguard Worker 
1021*f6dc9357SAndroid Build Coastguard Worker   {
1022*f6dc9357SAndroid Build Coastguard Worker     unsigned i = p->tableSize;
1023*f6dc9357SAndroid Build Coastguard Worker 
1024*f6dc9357SAndroid Build Coastguard Worker     if (i > kLenNumLowSymbols * 2)
1025*f6dc9357SAndroid Build Coastguard Worker     {
1026*f6dc9357SAndroid Build Coastguard Worker       const CLzmaProb *probs = enc->high;
1027*f6dc9357SAndroid Build Coastguard Worker       UInt32 *prices = p->prices[0] + kLenNumLowSymbols * 2;
1028*f6dc9357SAndroid Build Coastguard Worker       i -= kLenNumLowSymbols * 2 - 1;
1029*f6dc9357SAndroid Build Coastguard Worker       i >>= 1;
1030*f6dc9357SAndroid Build Coastguard Worker       b += GET_PRICEa_1(enc->low[kLenNumLowSymbols]);
1031*f6dc9357SAndroid Build Coastguard Worker       do
1032*f6dc9357SAndroid Build Coastguard Worker       {
1033*f6dc9357SAndroid Build Coastguard Worker         /*
1034*f6dc9357SAndroid Build Coastguard Worker         p->prices2[i] = a +
1035*f6dc9357SAndroid Build Coastguard Worker         // RcTree_GetPrice(enc->high, kLenNumHighBits, i - kLenNumLowSymbols * 2, ProbPrices);
1036*f6dc9357SAndroid Build Coastguard Worker         LitEnc_GetPrice(probs, i - kLenNumLowSymbols * 2, ProbPrices);
1037*f6dc9357SAndroid Build Coastguard Worker         */
1038*f6dc9357SAndroid Build Coastguard Worker         // UInt32 price = a + RcTree_GetPrice(probs, kLenNumHighBits - 1, sym, ProbPrices);
1039*f6dc9357SAndroid Build Coastguard Worker         unsigned sym = --i + (1 << (kLenNumHighBits - 1));
1040*f6dc9357SAndroid Build Coastguard Worker         UInt32 price = b;
1041*f6dc9357SAndroid Build Coastguard Worker         do
1042*f6dc9357SAndroid Build Coastguard Worker         {
1043*f6dc9357SAndroid Build Coastguard Worker           const unsigned bit = sym & 1;
1044*f6dc9357SAndroid Build Coastguard Worker           sym >>= 1;
1045*f6dc9357SAndroid Build Coastguard Worker           price += GET_PRICEa(probs[sym], bit);
1046*f6dc9357SAndroid Build Coastguard Worker         }
1047*f6dc9357SAndroid Build Coastguard Worker         while (sym >= 2);
1048*f6dc9357SAndroid Build Coastguard Worker 
1049*f6dc9357SAndroid Build Coastguard Worker         {
1050*f6dc9357SAndroid Build Coastguard Worker           const unsigned prob = probs[(size_t)i + (1 << (kLenNumHighBits - 1))];
1051*f6dc9357SAndroid Build Coastguard Worker           prices[(size_t)i * 2    ] = price + GET_PRICEa_0(prob);
1052*f6dc9357SAndroid Build Coastguard Worker           prices[(size_t)i * 2 + 1] = price + GET_PRICEa_1(prob);
1053*f6dc9357SAndroid Build Coastguard Worker         }
1054*f6dc9357SAndroid Build Coastguard Worker       }
1055*f6dc9357SAndroid Build Coastguard Worker       while (i);
1056*f6dc9357SAndroid Build Coastguard Worker 
1057*f6dc9357SAndroid Build Coastguard Worker       {
1058*f6dc9357SAndroid Build Coastguard Worker         unsigned posState;
1059*f6dc9357SAndroid Build Coastguard Worker         const size_t num = (p->tableSize - kLenNumLowSymbols * 2) * sizeof(p->prices[0][0]);
1060*f6dc9357SAndroid Build Coastguard Worker         for (posState = 1; posState < numPosStates; posState++)
1061*f6dc9357SAndroid Build Coastguard Worker           memcpy(p->prices[posState] + kLenNumLowSymbols * 2, p->prices[0] + kLenNumLowSymbols * 2, num);
1062*f6dc9357SAndroid Build Coastguard Worker       }
1063*f6dc9357SAndroid Build Coastguard Worker     }
1064*f6dc9357SAndroid Build Coastguard Worker   }
1065*f6dc9357SAndroid Build Coastguard Worker }
1066*f6dc9357SAndroid Build Coastguard Worker 
1067*f6dc9357SAndroid Build Coastguard Worker /*
1068*f6dc9357SAndroid Build Coastguard Worker   #ifdef SHOW_STAT
1069*f6dc9357SAndroid Build Coastguard Worker   g_STAT_OFFSET += num;
1070*f6dc9357SAndroid Build Coastguard Worker   printf("\n MovePos %u", num);
1071*f6dc9357SAndroid Build Coastguard Worker   #endif
1072*f6dc9357SAndroid Build Coastguard Worker */
1073*f6dc9357SAndroid Build Coastguard Worker 
1074*f6dc9357SAndroid Build Coastguard Worker #define MOVE_POS(p, num) { \
1075*f6dc9357SAndroid Build Coastguard Worker     p->additionalOffset += (num); \
1076*f6dc9357SAndroid Build Coastguard Worker     p->matchFinder.Skip(p->matchFinderObj, (UInt32)(num)); }
1077*f6dc9357SAndroid Build Coastguard Worker 
1078*f6dc9357SAndroid Build Coastguard Worker 
ReadMatchDistances(CLzmaEnc * p,unsigned * numPairsRes)1079*f6dc9357SAndroid Build Coastguard Worker static unsigned ReadMatchDistances(CLzmaEnc *p, unsigned *numPairsRes)
1080*f6dc9357SAndroid Build Coastguard Worker {
1081*f6dc9357SAndroid Build Coastguard Worker   unsigned numPairs;
1082*f6dc9357SAndroid Build Coastguard Worker 
1083*f6dc9357SAndroid Build Coastguard Worker   p->additionalOffset++;
1084*f6dc9357SAndroid Build Coastguard Worker   p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
1085*f6dc9357SAndroid Build Coastguard Worker   {
1086*f6dc9357SAndroid Build Coastguard Worker     const UInt32 *d = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
1087*f6dc9357SAndroid Build Coastguard Worker     // if (!d) { p->mf_Failure = True; *numPairsRes = 0;  return 0; }
1088*f6dc9357SAndroid Build Coastguard Worker     numPairs = (unsigned)(d - p->matches);
1089*f6dc9357SAndroid Build Coastguard Worker   }
1090*f6dc9357SAndroid Build Coastguard Worker   *numPairsRes = numPairs;
1091*f6dc9357SAndroid Build Coastguard Worker 
1092*f6dc9357SAndroid Build Coastguard Worker   #ifdef SHOW_STAT
1093*f6dc9357SAndroid Build Coastguard Worker   printf("\n i = %u numPairs = %u    ", g_STAT_OFFSET, numPairs / 2);
1094*f6dc9357SAndroid Build Coastguard Worker   g_STAT_OFFSET++;
1095*f6dc9357SAndroid Build Coastguard Worker   {
1096*f6dc9357SAndroid Build Coastguard Worker     unsigned i;
1097*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < numPairs; i += 2)
1098*f6dc9357SAndroid Build Coastguard Worker       printf("%2u %6u   | ", p->matches[i], p->matches[i + 1]);
1099*f6dc9357SAndroid Build Coastguard Worker   }
1100*f6dc9357SAndroid Build Coastguard Worker   #endif
1101*f6dc9357SAndroid Build Coastguard Worker 
1102*f6dc9357SAndroid Build Coastguard Worker   if (numPairs == 0)
1103*f6dc9357SAndroid Build Coastguard Worker     return 0;
1104*f6dc9357SAndroid Build Coastguard Worker   {
1105*f6dc9357SAndroid Build Coastguard Worker     const unsigned len = p->matches[(size_t)numPairs - 2];
1106*f6dc9357SAndroid Build Coastguard Worker     if (len != p->numFastBytes)
1107*f6dc9357SAndroid Build Coastguard Worker       return len;
1108*f6dc9357SAndroid Build Coastguard Worker     {
1109*f6dc9357SAndroid Build Coastguard Worker       UInt32 numAvail = p->numAvail;
1110*f6dc9357SAndroid Build Coastguard Worker       if (numAvail > LZMA_MATCH_LEN_MAX)
1111*f6dc9357SAndroid Build Coastguard Worker         numAvail = LZMA_MATCH_LEN_MAX;
1112*f6dc9357SAndroid Build Coastguard Worker       {
1113*f6dc9357SAndroid Build Coastguard Worker         const Byte *p1 = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
1114*f6dc9357SAndroid Build Coastguard Worker         const Byte *p2 = p1 + len;
1115*f6dc9357SAndroid Build Coastguard Worker         const ptrdiff_t dif = (ptrdiff_t)-1 - (ptrdiff_t)p->matches[(size_t)numPairs - 1];
1116*f6dc9357SAndroid Build Coastguard Worker         const Byte *lim = p1 + numAvail;
1117*f6dc9357SAndroid Build Coastguard Worker         for (; p2 != lim && *p2 == p2[dif]; p2++)
1118*f6dc9357SAndroid Build Coastguard Worker         {}
1119*f6dc9357SAndroid Build Coastguard Worker         return (unsigned)(p2 - p1);
1120*f6dc9357SAndroid Build Coastguard Worker       }
1121*f6dc9357SAndroid Build Coastguard Worker     }
1122*f6dc9357SAndroid Build Coastguard Worker   }
1123*f6dc9357SAndroid Build Coastguard Worker }
1124*f6dc9357SAndroid Build Coastguard Worker 
1125*f6dc9357SAndroid Build Coastguard Worker #define MARK_LIT ((UInt32)(Int32)-1)
1126*f6dc9357SAndroid Build Coastguard Worker 
1127*f6dc9357SAndroid Build Coastguard Worker #define MakeAs_Lit(p)       { (p)->dist = MARK_LIT; (p)->extra = 0; }
1128*f6dc9357SAndroid Build Coastguard Worker #define MakeAs_ShortRep(p)  { (p)->dist = 0; (p)->extra = 0; }
1129*f6dc9357SAndroid Build Coastguard Worker #define IsShortRep(p)       ((p)->dist == 0)
1130*f6dc9357SAndroid Build Coastguard Worker 
1131*f6dc9357SAndroid Build Coastguard Worker 
1132*f6dc9357SAndroid Build Coastguard Worker #define GetPrice_ShortRep(p, state, posState) \
1133*f6dc9357SAndroid Build Coastguard Worker   ( GET_PRICE_0(p->isRepG0[state]) + GET_PRICE_0(p->isRep0Long[state][posState]))
1134*f6dc9357SAndroid Build Coastguard Worker 
1135*f6dc9357SAndroid Build Coastguard Worker #define GetPrice_Rep_0(p, state, posState) ( \
1136*f6dc9357SAndroid Build Coastguard Worker     GET_PRICE_1(p->isMatch[state][posState]) \
1137*f6dc9357SAndroid Build Coastguard Worker   + GET_PRICE_1(p->isRep0Long[state][posState])) \
1138*f6dc9357SAndroid Build Coastguard Worker   + GET_PRICE_1(p->isRep[state]) \
1139*f6dc9357SAndroid Build Coastguard Worker   + GET_PRICE_0(p->isRepG0[state])
1140*f6dc9357SAndroid Build Coastguard Worker 
1141*f6dc9357SAndroid Build Coastguard Worker Z7_FORCE_INLINE
GetPrice_PureRep(const CLzmaEnc * p,unsigned repIndex,size_t state,size_t posState)1142*f6dc9357SAndroid Build Coastguard Worker static UInt32 GetPrice_PureRep(const CLzmaEnc *p, unsigned repIndex, size_t state, size_t posState)
1143*f6dc9357SAndroid Build Coastguard Worker {
1144*f6dc9357SAndroid Build Coastguard Worker   UInt32 price;
1145*f6dc9357SAndroid Build Coastguard Worker   UInt32 prob = p->isRepG0[state];
1146*f6dc9357SAndroid Build Coastguard Worker   if (repIndex == 0)
1147*f6dc9357SAndroid Build Coastguard Worker   {
1148*f6dc9357SAndroid Build Coastguard Worker     price = GET_PRICE_0(prob);
1149*f6dc9357SAndroid Build Coastguard Worker     price += GET_PRICE_1(p->isRep0Long[state][posState]);
1150*f6dc9357SAndroid Build Coastguard Worker   }
1151*f6dc9357SAndroid Build Coastguard Worker   else
1152*f6dc9357SAndroid Build Coastguard Worker   {
1153*f6dc9357SAndroid Build Coastguard Worker     price = GET_PRICE_1(prob);
1154*f6dc9357SAndroid Build Coastguard Worker     prob = p->isRepG1[state];
1155*f6dc9357SAndroid Build Coastguard Worker     if (repIndex == 1)
1156*f6dc9357SAndroid Build Coastguard Worker       price += GET_PRICE_0(prob);
1157*f6dc9357SAndroid Build Coastguard Worker     else
1158*f6dc9357SAndroid Build Coastguard Worker     {
1159*f6dc9357SAndroid Build Coastguard Worker       price += GET_PRICE_1(prob);
1160*f6dc9357SAndroid Build Coastguard Worker       price += GET_PRICE(p->isRepG2[state], repIndex - 2);
1161*f6dc9357SAndroid Build Coastguard Worker     }
1162*f6dc9357SAndroid Build Coastguard Worker   }
1163*f6dc9357SAndroid Build Coastguard Worker   return price;
1164*f6dc9357SAndroid Build Coastguard Worker }
1165*f6dc9357SAndroid Build Coastguard Worker 
1166*f6dc9357SAndroid Build Coastguard Worker 
Backward(CLzmaEnc * p,unsigned cur)1167*f6dc9357SAndroid Build Coastguard Worker static unsigned Backward(CLzmaEnc *p, unsigned cur)
1168*f6dc9357SAndroid Build Coastguard Worker {
1169*f6dc9357SAndroid Build Coastguard Worker   unsigned wr = cur + 1;
1170*f6dc9357SAndroid Build Coastguard Worker   p->optEnd = wr;
1171*f6dc9357SAndroid Build Coastguard Worker 
1172*f6dc9357SAndroid Build Coastguard Worker   for (;;)
1173*f6dc9357SAndroid Build Coastguard Worker   {
1174*f6dc9357SAndroid Build Coastguard Worker     UInt32 dist = p->opt[cur].dist;
1175*f6dc9357SAndroid Build Coastguard Worker     unsigned len = (unsigned)p->opt[cur].len;
1176*f6dc9357SAndroid Build Coastguard Worker     unsigned extra = (unsigned)p->opt[cur].extra;
1177*f6dc9357SAndroid Build Coastguard Worker     cur -= len;
1178*f6dc9357SAndroid Build Coastguard Worker 
1179*f6dc9357SAndroid Build Coastguard Worker     if (extra)
1180*f6dc9357SAndroid Build Coastguard Worker     {
1181*f6dc9357SAndroid Build Coastguard Worker       wr--;
1182*f6dc9357SAndroid Build Coastguard Worker       p->opt[wr].len = (UInt32)len;
1183*f6dc9357SAndroid Build Coastguard Worker       cur -= extra;
1184*f6dc9357SAndroid Build Coastguard Worker       len = extra;
1185*f6dc9357SAndroid Build Coastguard Worker       if (extra == 1)
1186*f6dc9357SAndroid Build Coastguard Worker       {
1187*f6dc9357SAndroid Build Coastguard Worker         p->opt[wr].dist = dist;
1188*f6dc9357SAndroid Build Coastguard Worker         dist = MARK_LIT;
1189*f6dc9357SAndroid Build Coastguard Worker       }
1190*f6dc9357SAndroid Build Coastguard Worker       else
1191*f6dc9357SAndroid Build Coastguard Worker       {
1192*f6dc9357SAndroid Build Coastguard Worker         p->opt[wr].dist = 0;
1193*f6dc9357SAndroid Build Coastguard Worker         len--;
1194*f6dc9357SAndroid Build Coastguard Worker         wr--;
1195*f6dc9357SAndroid Build Coastguard Worker         p->opt[wr].dist = MARK_LIT;
1196*f6dc9357SAndroid Build Coastguard Worker         p->opt[wr].len = 1;
1197*f6dc9357SAndroid Build Coastguard Worker       }
1198*f6dc9357SAndroid Build Coastguard Worker     }
1199*f6dc9357SAndroid Build Coastguard Worker 
1200*f6dc9357SAndroid Build Coastguard Worker     if (cur == 0)
1201*f6dc9357SAndroid Build Coastguard Worker     {
1202*f6dc9357SAndroid Build Coastguard Worker       p->backRes = dist;
1203*f6dc9357SAndroid Build Coastguard Worker       p->optCur = wr;
1204*f6dc9357SAndroid Build Coastguard Worker       return len;
1205*f6dc9357SAndroid Build Coastguard Worker     }
1206*f6dc9357SAndroid Build Coastguard Worker 
1207*f6dc9357SAndroid Build Coastguard Worker     wr--;
1208*f6dc9357SAndroid Build Coastguard Worker     p->opt[wr].dist = dist;
1209*f6dc9357SAndroid Build Coastguard Worker     p->opt[wr].len = (UInt32)len;
1210*f6dc9357SAndroid Build Coastguard Worker   }
1211*f6dc9357SAndroid Build Coastguard Worker }
1212*f6dc9357SAndroid Build Coastguard Worker 
1213*f6dc9357SAndroid Build Coastguard Worker 
1214*f6dc9357SAndroid Build Coastguard Worker 
1215*f6dc9357SAndroid Build Coastguard Worker #define LIT_PROBS(pos, prevByte) \
1216*f6dc9357SAndroid Build Coastguard Worker   (p->litProbs + (UInt32)3 * (((((pos) << 8) + (prevByte)) & p->lpMask) << p->lc))
1217*f6dc9357SAndroid Build Coastguard Worker 
1218*f6dc9357SAndroid Build Coastguard Worker 
GetOptimum(CLzmaEnc * p,UInt32 position)1219*f6dc9357SAndroid Build Coastguard Worker static unsigned GetOptimum(CLzmaEnc *p, UInt32 position)
1220*f6dc9357SAndroid Build Coastguard Worker {
1221*f6dc9357SAndroid Build Coastguard Worker   unsigned last, cur;
1222*f6dc9357SAndroid Build Coastguard Worker   UInt32 reps[LZMA_NUM_REPS];
1223*f6dc9357SAndroid Build Coastguard Worker   unsigned repLens[LZMA_NUM_REPS];
1224*f6dc9357SAndroid Build Coastguard Worker   UInt32 *matches;
1225*f6dc9357SAndroid Build Coastguard Worker 
1226*f6dc9357SAndroid Build Coastguard Worker   {
1227*f6dc9357SAndroid Build Coastguard Worker     UInt32 numAvail;
1228*f6dc9357SAndroid Build Coastguard Worker     unsigned numPairs, mainLen, repMaxIndex, i, posState;
1229*f6dc9357SAndroid Build Coastguard Worker     UInt32 matchPrice, repMatchPrice;
1230*f6dc9357SAndroid Build Coastguard Worker     const Byte *data;
1231*f6dc9357SAndroid Build Coastguard Worker     Byte curByte, matchByte;
1232*f6dc9357SAndroid Build Coastguard Worker 
1233*f6dc9357SAndroid Build Coastguard Worker     p->optCur = p->optEnd = 0;
1234*f6dc9357SAndroid Build Coastguard Worker 
1235*f6dc9357SAndroid Build Coastguard Worker     if (p->additionalOffset == 0)
1236*f6dc9357SAndroid Build Coastguard Worker       mainLen = ReadMatchDistances(p, &numPairs);
1237*f6dc9357SAndroid Build Coastguard Worker     else
1238*f6dc9357SAndroid Build Coastguard Worker     {
1239*f6dc9357SAndroid Build Coastguard Worker       mainLen = p->longestMatchLen;
1240*f6dc9357SAndroid Build Coastguard Worker       numPairs = p->numPairs;
1241*f6dc9357SAndroid Build Coastguard Worker     }
1242*f6dc9357SAndroid Build Coastguard Worker 
1243*f6dc9357SAndroid Build Coastguard Worker     numAvail = p->numAvail;
1244*f6dc9357SAndroid Build Coastguard Worker     if (numAvail < 2)
1245*f6dc9357SAndroid Build Coastguard Worker     {
1246*f6dc9357SAndroid Build Coastguard Worker       p->backRes = MARK_LIT;
1247*f6dc9357SAndroid Build Coastguard Worker       return 1;
1248*f6dc9357SAndroid Build Coastguard Worker     }
1249*f6dc9357SAndroid Build Coastguard Worker     if (numAvail > LZMA_MATCH_LEN_MAX)
1250*f6dc9357SAndroid Build Coastguard Worker       numAvail = LZMA_MATCH_LEN_MAX;
1251*f6dc9357SAndroid Build Coastguard Worker 
1252*f6dc9357SAndroid Build Coastguard Worker     data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
1253*f6dc9357SAndroid Build Coastguard Worker     repMaxIndex = 0;
1254*f6dc9357SAndroid Build Coastguard Worker 
1255*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < LZMA_NUM_REPS; i++)
1256*f6dc9357SAndroid Build Coastguard Worker     {
1257*f6dc9357SAndroid Build Coastguard Worker       unsigned len;
1258*f6dc9357SAndroid Build Coastguard Worker       const Byte *data2;
1259*f6dc9357SAndroid Build Coastguard Worker       reps[i] = p->reps[i];
1260*f6dc9357SAndroid Build Coastguard Worker       data2 = data - reps[i];
1261*f6dc9357SAndroid Build Coastguard Worker       if (data[0] != data2[0] || data[1] != data2[1])
1262*f6dc9357SAndroid Build Coastguard Worker       {
1263*f6dc9357SAndroid Build Coastguard Worker         repLens[i] = 0;
1264*f6dc9357SAndroid Build Coastguard Worker         continue;
1265*f6dc9357SAndroid Build Coastguard Worker       }
1266*f6dc9357SAndroid Build Coastguard Worker       for (len = 2; len < numAvail && data[len] == data2[len]; len++)
1267*f6dc9357SAndroid Build Coastguard Worker       {}
1268*f6dc9357SAndroid Build Coastguard Worker       repLens[i] = len;
1269*f6dc9357SAndroid Build Coastguard Worker       if (len > repLens[repMaxIndex])
1270*f6dc9357SAndroid Build Coastguard Worker         repMaxIndex = i;
1271*f6dc9357SAndroid Build Coastguard Worker       if (len == LZMA_MATCH_LEN_MAX) // 21.03 : optimization
1272*f6dc9357SAndroid Build Coastguard Worker         break;
1273*f6dc9357SAndroid Build Coastguard Worker     }
1274*f6dc9357SAndroid Build Coastguard Worker 
1275*f6dc9357SAndroid Build Coastguard Worker     if (repLens[repMaxIndex] >= p->numFastBytes)
1276*f6dc9357SAndroid Build Coastguard Worker     {
1277*f6dc9357SAndroid Build Coastguard Worker       unsigned len;
1278*f6dc9357SAndroid Build Coastguard Worker       p->backRes = (UInt32)repMaxIndex;
1279*f6dc9357SAndroid Build Coastguard Worker       len = repLens[repMaxIndex];
1280*f6dc9357SAndroid Build Coastguard Worker       MOVE_POS(p, len - 1)
1281*f6dc9357SAndroid Build Coastguard Worker       return len;
1282*f6dc9357SAndroid Build Coastguard Worker     }
1283*f6dc9357SAndroid Build Coastguard Worker 
1284*f6dc9357SAndroid Build Coastguard Worker     matches = p->matches;
1285*f6dc9357SAndroid Build Coastguard Worker     #define MATCHES  matches
1286*f6dc9357SAndroid Build Coastguard Worker     // #define MATCHES  p->matches
1287*f6dc9357SAndroid Build Coastguard Worker 
1288*f6dc9357SAndroid Build Coastguard Worker     if (mainLen >= p->numFastBytes)
1289*f6dc9357SAndroid Build Coastguard Worker     {
1290*f6dc9357SAndroid Build Coastguard Worker       p->backRes = MATCHES[(size_t)numPairs - 1] + LZMA_NUM_REPS;
1291*f6dc9357SAndroid Build Coastguard Worker       MOVE_POS(p, mainLen - 1)
1292*f6dc9357SAndroid Build Coastguard Worker       return mainLen;
1293*f6dc9357SAndroid Build Coastguard Worker     }
1294*f6dc9357SAndroid Build Coastguard Worker 
1295*f6dc9357SAndroid Build Coastguard Worker     curByte = *data;
1296*f6dc9357SAndroid Build Coastguard Worker     matchByte = *(data - reps[0]);
1297*f6dc9357SAndroid Build Coastguard Worker 
1298*f6dc9357SAndroid Build Coastguard Worker     last = repLens[repMaxIndex];
1299*f6dc9357SAndroid Build Coastguard Worker     if (last <= mainLen)
1300*f6dc9357SAndroid Build Coastguard Worker       last = mainLen;
1301*f6dc9357SAndroid Build Coastguard Worker 
1302*f6dc9357SAndroid Build Coastguard Worker     if (last < 2 && curByte != matchByte)
1303*f6dc9357SAndroid Build Coastguard Worker     {
1304*f6dc9357SAndroid Build Coastguard Worker       p->backRes = MARK_LIT;
1305*f6dc9357SAndroid Build Coastguard Worker       return 1;
1306*f6dc9357SAndroid Build Coastguard Worker     }
1307*f6dc9357SAndroid Build Coastguard Worker 
1308*f6dc9357SAndroid Build Coastguard Worker     p->opt[0].state = (CState)p->state;
1309*f6dc9357SAndroid Build Coastguard Worker 
1310*f6dc9357SAndroid Build Coastguard Worker     posState = (position & p->pbMask);
1311*f6dc9357SAndroid Build Coastguard Worker 
1312*f6dc9357SAndroid Build Coastguard Worker     {
1313*f6dc9357SAndroid Build Coastguard Worker       const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
1314*f6dc9357SAndroid Build Coastguard Worker       p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) +
1315*f6dc9357SAndroid Build Coastguard Worker         (!IsLitState(p->state) ?
1316*f6dc9357SAndroid Build Coastguard Worker           LitEnc_Matched_GetPrice(probs, curByte, matchByte, p->ProbPrices) :
1317*f6dc9357SAndroid Build Coastguard Worker           LitEnc_GetPrice(probs, curByte, p->ProbPrices));
1318*f6dc9357SAndroid Build Coastguard Worker     }
1319*f6dc9357SAndroid Build Coastguard Worker 
1320*f6dc9357SAndroid Build Coastguard Worker     MakeAs_Lit(&p->opt[1])
1321*f6dc9357SAndroid Build Coastguard Worker 
1322*f6dc9357SAndroid Build Coastguard Worker     matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]);
1323*f6dc9357SAndroid Build Coastguard Worker     repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]);
1324*f6dc9357SAndroid Build Coastguard Worker 
1325*f6dc9357SAndroid Build Coastguard Worker     // 18.06
1326*f6dc9357SAndroid Build Coastguard Worker     if (matchByte == curByte && repLens[0] == 0)
1327*f6dc9357SAndroid Build Coastguard Worker     {
1328*f6dc9357SAndroid Build Coastguard Worker       UInt32 shortRepPrice = repMatchPrice + GetPrice_ShortRep(p, p->state, posState);
1329*f6dc9357SAndroid Build Coastguard Worker       if (shortRepPrice < p->opt[1].price)
1330*f6dc9357SAndroid Build Coastguard Worker       {
1331*f6dc9357SAndroid Build Coastguard Worker         p->opt[1].price = shortRepPrice;
1332*f6dc9357SAndroid Build Coastguard Worker         MakeAs_ShortRep(&p->opt[1])
1333*f6dc9357SAndroid Build Coastguard Worker       }
1334*f6dc9357SAndroid Build Coastguard Worker       if (last < 2)
1335*f6dc9357SAndroid Build Coastguard Worker       {
1336*f6dc9357SAndroid Build Coastguard Worker         p->backRes = p->opt[1].dist;
1337*f6dc9357SAndroid Build Coastguard Worker         return 1;
1338*f6dc9357SAndroid Build Coastguard Worker       }
1339*f6dc9357SAndroid Build Coastguard Worker     }
1340*f6dc9357SAndroid Build Coastguard Worker 
1341*f6dc9357SAndroid Build Coastguard Worker     p->opt[1].len = 1;
1342*f6dc9357SAndroid Build Coastguard Worker 
1343*f6dc9357SAndroid Build Coastguard Worker     p->opt[0].reps[0] = reps[0];
1344*f6dc9357SAndroid Build Coastguard Worker     p->opt[0].reps[1] = reps[1];
1345*f6dc9357SAndroid Build Coastguard Worker     p->opt[0].reps[2] = reps[2];
1346*f6dc9357SAndroid Build Coastguard Worker     p->opt[0].reps[3] = reps[3];
1347*f6dc9357SAndroid Build Coastguard Worker 
1348*f6dc9357SAndroid Build Coastguard Worker     // ---------- REP ----------
1349*f6dc9357SAndroid Build Coastguard Worker 
1350*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < LZMA_NUM_REPS; i++)
1351*f6dc9357SAndroid Build Coastguard Worker     {
1352*f6dc9357SAndroid Build Coastguard Worker       unsigned repLen = repLens[i];
1353*f6dc9357SAndroid Build Coastguard Worker       UInt32 price;
1354*f6dc9357SAndroid Build Coastguard Worker       if (repLen < 2)
1355*f6dc9357SAndroid Build Coastguard Worker         continue;
1356*f6dc9357SAndroid Build Coastguard Worker       price = repMatchPrice + GetPrice_PureRep(p, i, p->state, posState);
1357*f6dc9357SAndroid Build Coastguard Worker       do
1358*f6dc9357SAndroid Build Coastguard Worker       {
1359*f6dc9357SAndroid Build Coastguard Worker         UInt32 price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState, repLen);
1360*f6dc9357SAndroid Build Coastguard Worker         COptimal *opt = &p->opt[repLen];
1361*f6dc9357SAndroid Build Coastguard Worker         if (price2 < opt->price)
1362*f6dc9357SAndroid Build Coastguard Worker         {
1363*f6dc9357SAndroid Build Coastguard Worker           opt->price = price2;
1364*f6dc9357SAndroid Build Coastguard Worker           opt->len = (UInt32)repLen;
1365*f6dc9357SAndroid Build Coastguard Worker           opt->dist = (UInt32)i;
1366*f6dc9357SAndroid Build Coastguard Worker           opt->extra = 0;
1367*f6dc9357SAndroid Build Coastguard Worker         }
1368*f6dc9357SAndroid Build Coastguard Worker       }
1369*f6dc9357SAndroid Build Coastguard Worker       while (--repLen >= 2);
1370*f6dc9357SAndroid Build Coastguard Worker     }
1371*f6dc9357SAndroid Build Coastguard Worker 
1372*f6dc9357SAndroid Build Coastguard Worker 
1373*f6dc9357SAndroid Build Coastguard Worker     // ---------- MATCH ----------
1374*f6dc9357SAndroid Build Coastguard Worker     {
1375*f6dc9357SAndroid Build Coastguard Worker       unsigned len = repLens[0] + 1;
1376*f6dc9357SAndroid Build Coastguard Worker       if (len <= mainLen)
1377*f6dc9357SAndroid Build Coastguard Worker       {
1378*f6dc9357SAndroid Build Coastguard Worker         unsigned offs = 0;
1379*f6dc9357SAndroid Build Coastguard Worker         UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]);
1380*f6dc9357SAndroid Build Coastguard Worker 
1381*f6dc9357SAndroid Build Coastguard Worker         if (len < 2)
1382*f6dc9357SAndroid Build Coastguard Worker           len = 2;
1383*f6dc9357SAndroid Build Coastguard Worker         else
1384*f6dc9357SAndroid Build Coastguard Worker           while (len > MATCHES[offs])
1385*f6dc9357SAndroid Build Coastguard Worker             offs += 2;
1386*f6dc9357SAndroid Build Coastguard Worker 
1387*f6dc9357SAndroid Build Coastguard Worker         for (; ; len++)
1388*f6dc9357SAndroid Build Coastguard Worker         {
1389*f6dc9357SAndroid Build Coastguard Worker           COptimal *opt;
1390*f6dc9357SAndroid Build Coastguard Worker           UInt32 dist = MATCHES[(size_t)offs + 1];
1391*f6dc9357SAndroid Build Coastguard Worker           UInt32 price = normalMatchPrice + GET_PRICE_LEN(&p->lenEnc, posState, len);
1392*f6dc9357SAndroid Build Coastguard Worker           unsigned lenToPosState = GetLenToPosState(len);
1393*f6dc9357SAndroid Build Coastguard Worker 
1394*f6dc9357SAndroid Build Coastguard Worker           if (dist < kNumFullDistances)
1395*f6dc9357SAndroid Build Coastguard Worker             price += p->distancesPrices[lenToPosState][dist & (kNumFullDistances - 1)];
1396*f6dc9357SAndroid Build Coastguard Worker           else
1397*f6dc9357SAndroid Build Coastguard Worker           {
1398*f6dc9357SAndroid Build Coastguard Worker             unsigned slot;
1399*f6dc9357SAndroid Build Coastguard Worker             GetPosSlot2(dist, slot)
1400*f6dc9357SAndroid Build Coastguard Worker             price += p->alignPrices[dist & kAlignMask];
1401*f6dc9357SAndroid Build Coastguard Worker             price += p->posSlotPrices[lenToPosState][slot];
1402*f6dc9357SAndroid Build Coastguard Worker           }
1403*f6dc9357SAndroid Build Coastguard Worker 
1404*f6dc9357SAndroid Build Coastguard Worker           opt = &p->opt[len];
1405*f6dc9357SAndroid Build Coastguard Worker 
1406*f6dc9357SAndroid Build Coastguard Worker           if (price < opt->price)
1407*f6dc9357SAndroid Build Coastguard Worker           {
1408*f6dc9357SAndroid Build Coastguard Worker             opt->price = price;
1409*f6dc9357SAndroid Build Coastguard Worker             opt->len = (UInt32)len;
1410*f6dc9357SAndroid Build Coastguard Worker             opt->dist = dist + LZMA_NUM_REPS;
1411*f6dc9357SAndroid Build Coastguard Worker             opt->extra = 0;
1412*f6dc9357SAndroid Build Coastguard Worker           }
1413*f6dc9357SAndroid Build Coastguard Worker 
1414*f6dc9357SAndroid Build Coastguard Worker           if (len == MATCHES[offs])
1415*f6dc9357SAndroid Build Coastguard Worker           {
1416*f6dc9357SAndroid Build Coastguard Worker             offs += 2;
1417*f6dc9357SAndroid Build Coastguard Worker             if (offs == numPairs)
1418*f6dc9357SAndroid Build Coastguard Worker               break;
1419*f6dc9357SAndroid Build Coastguard Worker           }
1420*f6dc9357SAndroid Build Coastguard Worker         }
1421*f6dc9357SAndroid Build Coastguard Worker       }
1422*f6dc9357SAndroid Build Coastguard Worker     }
1423*f6dc9357SAndroid Build Coastguard Worker 
1424*f6dc9357SAndroid Build Coastguard Worker 
1425*f6dc9357SAndroid Build Coastguard Worker     cur = 0;
1426*f6dc9357SAndroid Build Coastguard Worker 
1427*f6dc9357SAndroid Build Coastguard Worker     #ifdef SHOW_STAT2
1428*f6dc9357SAndroid Build Coastguard Worker     /* if (position >= 0) */
1429*f6dc9357SAndroid Build Coastguard Worker     {
1430*f6dc9357SAndroid Build Coastguard Worker       unsigned i;
1431*f6dc9357SAndroid Build Coastguard Worker       printf("\n pos = %4X", position);
1432*f6dc9357SAndroid Build Coastguard Worker       for (i = cur; i <= last; i++)
1433*f6dc9357SAndroid Build Coastguard Worker       printf("\nprice[%4X] = %u", position - cur + i, p->opt[i].price);
1434*f6dc9357SAndroid Build Coastguard Worker     }
1435*f6dc9357SAndroid Build Coastguard Worker     #endif
1436*f6dc9357SAndroid Build Coastguard Worker   }
1437*f6dc9357SAndroid Build Coastguard Worker 
1438*f6dc9357SAndroid Build Coastguard Worker 
1439*f6dc9357SAndroid Build Coastguard Worker 
1440*f6dc9357SAndroid Build Coastguard Worker   // ---------- Optimal Parsing ----------
1441*f6dc9357SAndroid Build Coastguard Worker 
1442*f6dc9357SAndroid Build Coastguard Worker   for (;;)
1443*f6dc9357SAndroid Build Coastguard Worker   {
1444*f6dc9357SAndroid Build Coastguard Worker     unsigned numAvail;
1445*f6dc9357SAndroid Build Coastguard Worker     UInt32 numAvailFull;
1446*f6dc9357SAndroid Build Coastguard Worker     unsigned newLen, numPairs, prev, state, posState, startLen;
1447*f6dc9357SAndroid Build Coastguard Worker     UInt32 litPrice, matchPrice, repMatchPrice;
1448*f6dc9357SAndroid Build Coastguard Worker     BoolInt nextIsLit;
1449*f6dc9357SAndroid Build Coastguard Worker     Byte curByte, matchByte;
1450*f6dc9357SAndroid Build Coastguard Worker     const Byte *data;
1451*f6dc9357SAndroid Build Coastguard Worker     COptimal *curOpt, *nextOpt;
1452*f6dc9357SAndroid Build Coastguard Worker 
1453*f6dc9357SAndroid Build Coastguard Worker     if (++cur == last)
1454*f6dc9357SAndroid Build Coastguard Worker       break;
1455*f6dc9357SAndroid Build Coastguard Worker 
1456*f6dc9357SAndroid Build Coastguard Worker     // 18.06
1457*f6dc9357SAndroid Build Coastguard Worker     if (cur >= kNumOpts - 64)
1458*f6dc9357SAndroid Build Coastguard Worker     {
1459*f6dc9357SAndroid Build Coastguard Worker       unsigned j, best;
1460*f6dc9357SAndroid Build Coastguard Worker       UInt32 price = p->opt[cur].price;
1461*f6dc9357SAndroid Build Coastguard Worker       best = cur;
1462*f6dc9357SAndroid Build Coastguard Worker       for (j = cur + 1; j <= last; j++)
1463*f6dc9357SAndroid Build Coastguard Worker       {
1464*f6dc9357SAndroid Build Coastguard Worker         UInt32 price2 = p->opt[j].price;
1465*f6dc9357SAndroid Build Coastguard Worker         if (price >= price2)
1466*f6dc9357SAndroid Build Coastguard Worker         {
1467*f6dc9357SAndroid Build Coastguard Worker           price = price2;
1468*f6dc9357SAndroid Build Coastguard Worker           best = j;
1469*f6dc9357SAndroid Build Coastguard Worker         }
1470*f6dc9357SAndroid Build Coastguard Worker       }
1471*f6dc9357SAndroid Build Coastguard Worker       {
1472*f6dc9357SAndroid Build Coastguard Worker         unsigned delta = best - cur;
1473*f6dc9357SAndroid Build Coastguard Worker         if (delta != 0)
1474*f6dc9357SAndroid Build Coastguard Worker         {
1475*f6dc9357SAndroid Build Coastguard Worker           MOVE_POS(p, delta)
1476*f6dc9357SAndroid Build Coastguard Worker         }
1477*f6dc9357SAndroid Build Coastguard Worker       }
1478*f6dc9357SAndroid Build Coastguard Worker       cur = best;
1479*f6dc9357SAndroid Build Coastguard Worker       break;
1480*f6dc9357SAndroid Build Coastguard Worker     }
1481*f6dc9357SAndroid Build Coastguard Worker 
1482*f6dc9357SAndroid Build Coastguard Worker     newLen = ReadMatchDistances(p, &numPairs);
1483*f6dc9357SAndroid Build Coastguard Worker 
1484*f6dc9357SAndroid Build Coastguard Worker     if (newLen >= p->numFastBytes)
1485*f6dc9357SAndroid Build Coastguard Worker     {
1486*f6dc9357SAndroid Build Coastguard Worker       p->numPairs = numPairs;
1487*f6dc9357SAndroid Build Coastguard Worker       p->longestMatchLen = newLen;
1488*f6dc9357SAndroid Build Coastguard Worker       break;
1489*f6dc9357SAndroid Build Coastguard Worker     }
1490*f6dc9357SAndroid Build Coastguard Worker 
1491*f6dc9357SAndroid Build Coastguard Worker     curOpt = &p->opt[cur];
1492*f6dc9357SAndroid Build Coastguard Worker 
1493*f6dc9357SAndroid Build Coastguard Worker     position++;
1494*f6dc9357SAndroid Build Coastguard Worker 
1495*f6dc9357SAndroid Build Coastguard Worker     // we need that check here, if skip_items in p->opt are possible
1496*f6dc9357SAndroid Build Coastguard Worker     /*
1497*f6dc9357SAndroid Build Coastguard Worker     if (curOpt->price >= kInfinityPrice)
1498*f6dc9357SAndroid Build Coastguard Worker       continue;
1499*f6dc9357SAndroid Build Coastguard Worker     */
1500*f6dc9357SAndroid Build Coastguard Worker 
1501*f6dc9357SAndroid Build Coastguard Worker     prev = cur - curOpt->len;
1502*f6dc9357SAndroid Build Coastguard Worker 
1503*f6dc9357SAndroid Build Coastguard Worker     if (curOpt->len == 1)
1504*f6dc9357SAndroid Build Coastguard Worker     {
1505*f6dc9357SAndroid Build Coastguard Worker       state = (unsigned)p->opt[prev].state;
1506*f6dc9357SAndroid Build Coastguard Worker       if (IsShortRep(curOpt))
1507*f6dc9357SAndroid Build Coastguard Worker         state = kShortRepNextStates[state];
1508*f6dc9357SAndroid Build Coastguard Worker       else
1509*f6dc9357SAndroid Build Coastguard Worker         state = kLiteralNextStates[state];
1510*f6dc9357SAndroid Build Coastguard Worker     }
1511*f6dc9357SAndroid Build Coastguard Worker     else
1512*f6dc9357SAndroid Build Coastguard Worker     {
1513*f6dc9357SAndroid Build Coastguard Worker       const COptimal *prevOpt;
1514*f6dc9357SAndroid Build Coastguard Worker       UInt32 b0;
1515*f6dc9357SAndroid Build Coastguard Worker       UInt32 dist = curOpt->dist;
1516*f6dc9357SAndroid Build Coastguard Worker 
1517*f6dc9357SAndroid Build Coastguard Worker       if (curOpt->extra)
1518*f6dc9357SAndroid Build Coastguard Worker       {
1519*f6dc9357SAndroid Build Coastguard Worker         prev -= (unsigned)curOpt->extra;
1520*f6dc9357SAndroid Build Coastguard Worker         state = kState_RepAfterLit;
1521*f6dc9357SAndroid Build Coastguard Worker         if (curOpt->extra == 1)
1522*f6dc9357SAndroid Build Coastguard Worker           state = (dist < LZMA_NUM_REPS ? kState_RepAfterLit : kState_MatchAfterLit);
1523*f6dc9357SAndroid Build Coastguard Worker       }
1524*f6dc9357SAndroid Build Coastguard Worker       else
1525*f6dc9357SAndroid Build Coastguard Worker       {
1526*f6dc9357SAndroid Build Coastguard Worker         state = (unsigned)p->opt[prev].state;
1527*f6dc9357SAndroid Build Coastguard Worker         if (dist < LZMA_NUM_REPS)
1528*f6dc9357SAndroid Build Coastguard Worker           state = kRepNextStates[state];
1529*f6dc9357SAndroid Build Coastguard Worker         else
1530*f6dc9357SAndroid Build Coastguard Worker           state = kMatchNextStates[state];
1531*f6dc9357SAndroid Build Coastguard Worker       }
1532*f6dc9357SAndroid Build Coastguard Worker 
1533*f6dc9357SAndroid Build Coastguard Worker       prevOpt = &p->opt[prev];
1534*f6dc9357SAndroid Build Coastguard Worker       b0 = prevOpt->reps[0];
1535*f6dc9357SAndroid Build Coastguard Worker 
1536*f6dc9357SAndroid Build Coastguard Worker       if (dist < LZMA_NUM_REPS)
1537*f6dc9357SAndroid Build Coastguard Worker       {
1538*f6dc9357SAndroid Build Coastguard Worker         if (dist == 0)
1539*f6dc9357SAndroid Build Coastguard Worker         {
1540*f6dc9357SAndroid Build Coastguard Worker           reps[0] = b0;
1541*f6dc9357SAndroid Build Coastguard Worker           reps[1] = prevOpt->reps[1];
1542*f6dc9357SAndroid Build Coastguard Worker           reps[2] = prevOpt->reps[2];
1543*f6dc9357SAndroid Build Coastguard Worker           reps[3] = prevOpt->reps[3];
1544*f6dc9357SAndroid Build Coastguard Worker         }
1545*f6dc9357SAndroid Build Coastguard Worker         else
1546*f6dc9357SAndroid Build Coastguard Worker         {
1547*f6dc9357SAndroid Build Coastguard Worker           reps[1] = b0;
1548*f6dc9357SAndroid Build Coastguard Worker           b0 = prevOpt->reps[1];
1549*f6dc9357SAndroid Build Coastguard Worker           if (dist == 1)
1550*f6dc9357SAndroid Build Coastguard Worker           {
1551*f6dc9357SAndroid Build Coastguard Worker             reps[0] = b0;
1552*f6dc9357SAndroid Build Coastguard Worker             reps[2] = prevOpt->reps[2];
1553*f6dc9357SAndroid Build Coastguard Worker             reps[3] = prevOpt->reps[3];
1554*f6dc9357SAndroid Build Coastguard Worker           }
1555*f6dc9357SAndroid Build Coastguard Worker           else
1556*f6dc9357SAndroid Build Coastguard Worker           {
1557*f6dc9357SAndroid Build Coastguard Worker             reps[2] = b0;
1558*f6dc9357SAndroid Build Coastguard Worker             reps[0] = prevOpt->reps[dist];
1559*f6dc9357SAndroid Build Coastguard Worker             reps[3] = prevOpt->reps[dist ^ 1];
1560*f6dc9357SAndroid Build Coastguard Worker           }
1561*f6dc9357SAndroid Build Coastguard Worker         }
1562*f6dc9357SAndroid Build Coastguard Worker       }
1563*f6dc9357SAndroid Build Coastguard Worker       else
1564*f6dc9357SAndroid Build Coastguard Worker       {
1565*f6dc9357SAndroid Build Coastguard Worker         reps[0] = (dist - LZMA_NUM_REPS + 1);
1566*f6dc9357SAndroid Build Coastguard Worker         reps[1] = b0;
1567*f6dc9357SAndroid Build Coastguard Worker         reps[2] = prevOpt->reps[1];
1568*f6dc9357SAndroid Build Coastguard Worker         reps[3] = prevOpt->reps[2];
1569*f6dc9357SAndroid Build Coastguard Worker       }
1570*f6dc9357SAndroid Build Coastguard Worker     }
1571*f6dc9357SAndroid Build Coastguard Worker 
1572*f6dc9357SAndroid Build Coastguard Worker     curOpt->state = (CState)state;
1573*f6dc9357SAndroid Build Coastguard Worker     curOpt->reps[0] = reps[0];
1574*f6dc9357SAndroid Build Coastguard Worker     curOpt->reps[1] = reps[1];
1575*f6dc9357SAndroid Build Coastguard Worker     curOpt->reps[2] = reps[2];
1576*f6dc9357SAndroid Build Coastguard Worker     curOpt->reps[3] = reps[3];
1577*f6dc9357SAndroid Build Coastguard Worker 
1578*f6dc9357SAndroid Build Coastguard Worker     data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
1579*f6dc9357SAndroid Build Coastguard Worker     curByte = *data;
1580*f6dc9357SAndroid Build Coastguard Worker     matchByte = *(data - reps[0]);
1581*f6dc9357SAndroid Build Coastguard Worker 
1582*f6dc9357SAndroid Build Coastguard Worker     posState = (position & p->pbMask);
1583*f6dc9357SAndroid Build Coastguard Worker 
1584*f6dc9357SAndroid Build Coastguard Worker     /*
1585*f6dc9357SAndroid Build Coastguard Worker     The order of Price checks:
1586*f6dc9357SAndroid Build Coastguard Worker        <  LIT
1587*f6dc9357SAndroid Build Coastguard Worker        <= SHORT_REP
1588*f6dc9357SAndroid Build Coastguard Worker        <  LIT : REP_0
1589*f6dc9357SAndroid Build Coastguard Worker        <  REP    [ : LIT : REP_0 ]
1590*f6dc9357SAndroid Build Coastguard Worker        <  MATCH  [ : LIT : REP_0 ]
1591*f6dc9357SAndroid Build Coastguard Worker     */
1592*f6dc9357SAndroid Build Coastguard Worker 
1593*f6dc9357SAndroid Build Coastguard Worker     {
1594*f6dc9357SAndroid Build Coastguard Worker       UInt32 curPrice = curOpt->price;
1595*f6dc9357SAndroid Build Coastguard Worker       unsigned prob = p->isMatch[state][posState];
1596*f6dc9357SAndroid Build Coastguard Worker       matchPrice = curPrice + GET_PRICE_1(prob);
1597*f6dc9357SAndroid Build Coastguard Worker       litPrice = curPrice + GET_PRICE_0(prob);
1598*f6dc9357SAndroid Build Coastguard Worker     }
1599*f6dc9357SAndroid Build Coastguard Worker 
1600*f6dc9357SAndroid Build Coastguard Worker     nextOpt = &p->opt[(size_t)cur + 1];
1601*f6dc9357SAndroid Build Coastguard Worker     nextIsLit = False;
1602*f6dc9357SAndroid Build Coastguard Worker 
1603*f6dc9357SAndroid Build Coastguard Worker     // here we can allow skip_items in p->opt, if we don't check (nextOpt->price < kInfinityPrice)
1604*f6dc9357SAndroid Build Coastguard Worker     // 18.new.06
1605*f6dc9357SAndroid Build Coastguard Worker     if ((nextOpt->price < kInfinityPrice
1606*f6dc9357SAndroid Build Coastguard Worker         // && !IsLitState(state)
1607*f6dc9357SAndroid Build Coastguard Worker         && matchByte == curByte)
1608*f6dc9357SAndroid Build Coastguard Worker         || litPrice > nextOpt->price
1609*f6dc9357SAndroid Build Coastguard Worker         )
1610*f6dc9357SAndroid Build Coastguard Worker       litPrice = 0;
1611*f6dc9357SAndroid Build Coastguard Worker     else
1612*f6dc9357SAndroid Build Coastguard Worker     {
1613*f6dc9357SAndroid Build Coastguard Worker       const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
1614*f6dc9357SAndroid Build Coastguard Worker       litPrice += (!IsLitState(state) ?
1615*f6dc9357SAndroid Build Coastguard Worker           LitEnc_Matched_GetPrice(probs, curByte, matchByte, p->ProbPrices) :
1616*f6dc9357SAndroid Build Coastguard Worker           LitEnc_GetPrice(probs, curByte, p->ProbPrices));
1617*f6dc9357SAndroid Build Coastguard Worker 
1618*f6dc9357SAndroid Build Coastguard Worker       if (litPrice < nextOpt->price)
1619*f6dc9357SAndroid Build Coastguard Worker       {
1620*f6dc9357SAndroid Build Coastguard Worker         nextOpt->price = litPrice;
1621*f6dc9357SAndroid Build Coastguard Worker         nextOpt->len = 1;
1622*f6dc9357SAndroid Build Coastguard Worker         MakeAs_Lit(nextOpt)
1623*f6dc9357SAndroid Build Coastguard Worker         nextIsLit = True;
1624*f6dc9357SAndroid Build Coastguard Worker       }
1625*f6dc9357SAndroid Build Coastguard Worker     }
1626*f6dc9357SAndroid Build Coastguard Worker 
1627*f6dc9357SAndroid Build Coastguard Worker     repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]);
1628*f6dc9357SAndroid Build Coastguard Worker 
1629*f6dc9357SAndroid Build Coastguard Worker     numAvailFull = p->numAvail;
1630*f6dc9357SAndroid Build Coastguard Worker     {
1631*f6dc9357SAndroid Build Coastguard Worker       unsigned temp = kNumOpts - 1 - cur;
1632*f6dc9357SAndroid Build Coastguard Worker       if (numAvailFull > temp)
1633*f6dc9357SAndroid Build Coastguard Worker         numAvailFull = (UInt32)temp;
1634*f6dc9357SAndroid Build Coastguard Worker     }
1635*f6dc9357SAndroid Build Coastguard Worker 
1636*f6dc9357SAndroid Build Coastguard Worker     // 18.06
1637*f6dc9357SAndroid Build Coastguard Worker     // ---------- SHORT_REP ----------
1638*f6dc9357SAndroid Build Coastguard Worker     if (IsLitState(state)) // 18.new
1639*f6dc9357SAndroid Build Coastguard Worker     if (matchByte == curByte)
1640*f6dc9357SAndroid Build Coastguard Worker     if (repMatchPrice < nextOpt->price) // 18.new
1641*f6dc9357SAndroid Build Coastguard Worker     // if (numAvailFull < 2 || data[1] != *(data - reps[0] + 1))
1642*f6dc9357SAndroid Build Coastguard Worker     if (
1643*f6dc9357SAndroid Build Coastguard Worker         // nextOpt->price >= kInfinityPrice ||
1644*f6dc9357SAndroid Build Coastguard Worker         nextOpt->len < 2   // we can check nextOpt->len, if skip items are not allowed in p->opt
1645*f6dc9357SAndroid Build Coastguard Worker         || (nextOpt->dist != 0
1646*f6dc9357SAndroid Build Coastguard Worker             // && nextOpt->extra <= 1 // 17.old
1647*f6dc9357SAndroid Build Coastguard Worker             )
1648*f6dc9357SAndroid Build Coastguard Worker         )
1649*f6dc9357SAndroid Build Coastguard Worker     {
1650*f6dc9357SAndroid Build Coastguard Worker       UInt32 shortRepPrice = repMatchPrice + GetPrice_ShortRep(p, state, posState);
1651*f6dc9357SAndroid Build Coastguard Worker       // if (shortRepPrice <= nextOpt->price) // 17.old
1652*f6dc9357SAndroid Build Coastguard Worker       if (shortRepPrice < nextOpt->price)  // 18.new
1653*f6dc9357SAndroid Build Coastguard Worker       {
1654*f6dc9357SAndroid Build Coastguard Worker         nextOpt->price = shortRepPrice;
1655*f6dc9357SAndroid Build Coastguard Worker         nextOpt->len = 1;
1656*f6dc9357SAndroid Build Coastguard Worker         MakeAs_ShortRep(nextOpt)
1657*f6dc9357SAndroid Build Coastguard Worker         nextIsLit = False;
1658*f6dc9357SAndroid Build Coastguard Worker       }
1659*f6dc9357SAndroid Build Coastguard Worker     }
1660*f6dc9357SAndroid Build Coastguard Worker 
1661*f6dc9357SAndroid Build Coastguard Worker     if (numAvailFull < 2)
1662*f6dc9357SAndroid Build Coastguard Worker       continue;
1663*f6dc9357SAndroid Build Coastguard Worker     numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes);
1664*f6dc9357SAndroid Build Coastguard Worker 
1665*f6dc9357SAndroid Build Coastguard Worker     // numAvail <= p->numFastBytes
1666*f6dc9357SAndroid Build Coastguard Worker 
1667*f6dc9357SAndroid Build Coastguard Worker     // ---------- LIT : REP_0 ----------
1668*f6dc9357SAndroid Build Coastguard Worker 
1669*f6dc9357SAndroid Build Coastguard Worker     if (!nextIsLit
1670*f6dc9357SAndroid Build Coastguard Worker         && litPrice != 0 // 18.new
1671*f6dc9357SAndroid Build Coastguard Worker         && matchByte != curByte
1672*f6dc9357SAndroid Build Coastguard Worker         && numAvailFull > 2)
1673*f6dc9357SAndroid Build Coastguard Worker     {
1674*f6dc9357SAndroid Build Coastguard Worker       const Byte *data2 = data - reps[0];
1675*f6dc9357SAndroid Build Coastguard Worker       if (data[1] == data2[1] && data[2] == data2[2])
1676*f6dc9357SAndroid Build Coastguard Worker       {
1677*f6dc9357SAndroid Build Coastguard Worker         unsigned len;
1678*f6dc9357SAndroid Build Coastguard Worker         unsigned limit = p->numFastBytes + 1;
1679*f6dc9357SAndroid Build Coastguard Worker         if (limit > numAvailFull)
1680*f6dc9357SAndroid Build Coastguard Worker           limit = numAvailFull;
1681*f6dc9357SAndroid Build Coastguard Worker         for (len = 3; len < limit && data[len] == data2[len]; len++)
1682*f6dc9357SAndroid Build Coastguard Worker         {}
1683*f6dc9357SAndroid Build Coastguard Worker 
1684*f6dc9357SAndroid Build Coastguard Worker         {
1685*f6dc9357SAndroid Build Coastguard Worker           unsigned state2 = kLiteralNextStates[state];
1686*f6dc9357SAndroid Build Coastguard Worker           unsigned posState2 = (position + 1) & p->pbMask;
1687*f6dc9357SAndroid Build Coastguard Worker           UInt32 price = litPrice + GetPrice_Rep_0(p, state2, posState2);
1688*f6dc9357SAndroid Build Coastguard Worker           {
1689*f6dc9357SAndroid Build Coastguard Worker             unsigned offset = cur + len;
1690*f6dc9357SAndroid Build Coastguard Worker 
1691*f6dc9357SAndroid Build Coastguard Worker             if (last < offset)
1692*f6dc9357SAndroid Build Coastguard Worker               last = offset;
1693*f6dc9357SAndroid Build Coastguard Worker 
1694*f6dc9357SAndroid Build Coastguard Worker             // do
1695*f6dc9357SAndroid Build Coastguard Worker             {
1696*f6dc9357SAndroid Build Coastguard Worker               UInt32 price2;
1697*f6dc9357SAndroid Build Coastguard Worker               COptimal *opt;
1698*f6dc9357SAndroid Build Coastguard Worker               len--;
1699*f6dc9357SAndroid Build Coastguard Worker               // price2 = price + GetPrice_Len_Rep_0(p, len, state2, posState2);
1700*f6dc9357SAndroid Build Coastguard Worker               price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState2, len);
1701*f6dc9357SAndroid Build Coastguard Worker 
1702*f6dc9357SAndroid Build Coastguard Worker               opt = &p->opt[offset];
1703*f6dc9357SAndroid Build Coastguard Worker               // offset--;
1704*f6dc9357SAndroid Build Coastguard Worker               if (price2 < opt->price)
1705*f6dc9357SAndroid Build Coastguard Worker               {
1706*f6dc9357SAndroid Build Coastguard Worker                 opt->price = price2;
1707*f6dc9357SAndroid Build Coastguard Worker                 opt->len = (UInt32)len;
1708*f6dc9357SAndroid Build Coastguard Worker                 opt->dist = 0;
1709*f6dc9357SAndroid Build Coastguard Worker                 opt->extra = 1;
1710*f6dc9357SAndroid Build Coastguard Worker               }
1711*f6dc9357SAndroid Build Coastguard Worker             }
1712*f6dc9357SAndroid Build Coastguard Worker             // while (len >= 3);
1713*f6dc9357SAndroid Build Coastguard Worker           }
1714*f6dc9357SAndroid Build Coastguard Worker         }
1715*f6dc9357SAndroid Build Coastguard Worker       }
1716*f6dc9357SAndroid Build Coastguard Worker     }
1717*f6dc9357SAndroid Build Coastguard Worker 
1718*f6dc9357SAndroid Build Coastguard Worker     startLen = 2; /* speed optimization */
1719*f6dc9357SAndroid Build Coastguard Worker 
1720*f6dc9357SAndroid Build Coastguard Worker     {
1721*f6dc9357SAndroid Build Coastguard Worker       // ---------- REP ----------
1722*f6dc9357SAndroid Build Coastguard Worker       unsigned repIndex = 0; // 17.old
1723*f6dc9357SAndroid Build Coastguard Worker       // unsigned repIndex = IsLitState(state) ? 0 : 1; // 18.notused
1724*f6dc9357SAndroid Build Coastguard Worker       for (; repIndex < LZMA_NUM_REPS; repIndex++)
1725*f6dc9357SAndroid Build Coastguard Worker       {
1726*f6dc9357SAndroid Build Coastguard Worker         unsigned len;
1727*f6dc9357SAndroid Build Coastguard Worker         UInt32 price;
1728*f6dc9357SAndroid Build Coastguard Worker         const Byte *data2 = data - reps[repIndex];
1729*f6dc9357SAndroid Build Coastguard Worker         if (data[0] != data2[0] || data[1] != data2[1])
1730*f6dc9357SAndroid Build Coastguard Worker           continue;
1731*f6dc9357SAndroid Build Coastguard Worker 
1732*f6dc9357SAndroid Build Coastguard Worker         for (len = 2; len < numAvail && data[len] == data2[len]; len++)
1733*f6dc9357SAndroid Build Coastguard Worker         {}
1734*f6dc9357SAndroid Build Coastguard Worker 
1735*f6dc9357SAndroid Build Coastguard Worker         // if (len < startLen) continue; // 18.new: speed optimization
1736*f6dc9357SAndroid Build Coastguard Worker 
1737*f6dc9357SAndroid Build Coastguard Worker         {
1738*f6dc9357SAndroid Build Coastguard Worker           unsigned offset = cur + len;
1739*f6dc9357SAndroid Build Coastguard Worker           if (last < offset)
1740*f6dc9357SAndroid Build Coastguard Worker             last = offset;
1741*f6dc9357SAndroid Build Coastguard Worker         }
1742*f6dc9357SAndroid Build Coastguard Worker         {
1743*f6dc9357SAndroid Build Coastguard Worker           unsigned len2 = len;
1744*f6dc9357SAndroid Build Coastguard Worker           price = repMatchPrice + GetPrice_PureRep(p, repIndex, state, posState);
1745*f6dc9357SAndroid Build Coastguard Worker           do
1746*f6dc9357SAndroid Build Coastguard Worker           {
1747*f6dc9357SAndroid Build Coastguard Worker             UInt32 price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState, len2);
1748*f6dc9357SAndroid Build Coastguard Worker             COptimal *opt = &p->opt[cur + len2];
1749*f6dc9357SAndroid Build Coastguard Worker             if (price2 < opt->price)
1750*f6dc9357SAndroid Build Coastguard Worker             {
1751*f6dc9357SAndroid Build Coastguard Worker               opt->price = price2;
1752*f6dc9357SAndroid Build Coastguard Worker               opt->len = (UInt32)len2;
1753*f6dc9357SAndroid Build Coastguard Worker               opt->dist = (UInt32)repIndex;
1754*f6dc9357SAndroid Build Coastguard Worker               opt->extra = 0;
1755*f6dc9357SAndroid Build Coastguard Worker             }
1756*f6dc9357SAndroid Build Coastguard Worker           }
1757*f6dc9357SAndroid Build Coastguard Worker           while (--len2 >= 2);
1758*f6dc9357SAndroid Build Coastguard Worker         }
1759*f6dc9357SAndroid Build Coastguard Worker 
1760*f6dc9357SAndroid Build Coastguard Worker         if (repIndex == 0) startLen = len + 1;  // 17.old
1761*f6dc9357SAndroid Build Coastguard Worker         // startLen = len + 1; // 18.new
1762*f6dc9357SAndroid Build Coastguard Worker 
1763*f6dc9357SAndroid Build Coastguard Worker         /* if (_maxMode) */
1764*f6dc9357SAndroid Build Coastguard Worker         {
1765*f6dc9357SAndroid Build Coastguard Worker           // ---------- REP : LIT : REP_0 ----------
1766*f6dc9357SAndroid Build Coastguard Worker           // numFastBytes + 1 + numFastBytes
1767*f6dc9357SAndroid Build Coastguard Worker 
1768*f6dc9357SAndroid Build Coastguard Worker           unsigned len2 = len + 1;
1769*f6dc9357SAndroid Build Coastguard Worker           unsigned limit = len2 + p->numFastBytes;
1770*f6dc9357SAndroid Build Coastguard Worker           if (limit > numAvailFull)
1771*f6dc9357SAndroid Build Coastguard Worker             limit = numAvailFull;
1772*f6dc9357SAndroid Build Coastguard Worker 
1773*f6dc9357SAndroid Build Coastguard Worker           len2 += 2;
1774*f6dc9357SAndroid Build Coastguard Worker           if (len2 <= limit)
1775*f6dc9357SAndroid Build Coastguard Worker           if (data[len2 - 2] == data2[len2 - 2])
1776*f6dc9357SAndroid Build Coastguard Worker           if (data[len2 - 1] == data2[len2 - 1])
1777*f6dc9357SAndroid Build Coastguard Worker           {
1778*f6dc9357SAndroid Build Coastguard Worker             unsigned state2 = kRepNextStates[state];
1779*f6dc9357SAndroid Build Coastguard Worker             unsigned posState2 = (position + len) & p->pbMask;
1780*f6dc9357SAndroid Build Coastguard Worker             price += GET_PRICE_LEN(&p->repLenEnc, posState, len)
1781*f6dc9357SAndroid Build Coastguard Worker                 + GET_PRICE_0(p->isMatch[state2][posState2])
1782*f6dc9357SAndroid Build Coastguard Worker                 + LitEnc_Matched_GetPrice(LIT_PROBS(position + len, data[(size_t)len - 1]),
1783*f6dc9357SAndroid Build Coastguard Worker                     data[len], data2[len], p->ProbPrices);
1784*f6dc9357SAndroid Build Coastguard Worker 
1785*f6dc9357SAndroid Build Coastguard Worker             // state2 = kLiteralNextStates[state2];
1786*f6dc9357SAndroid Build Coastguard Worker             state2 = kState_LitAfterRep;
1787*f6dc9357SAndroid Build Coastguard Worker             posState2 = (posState2 + 1) & p->pbMask;
1788*f6dc9357SAndroid Build Coastguard Worker 
1789*f6dc9357SAndroid Build Coastguard Worker 
1790*f6dc9357SAndroid Build Coastguard Worker             price += GetPrice_Rep_0(p, state2, posState2);
1791*f6dc9357SAndroid Build Coastguard Worker 
1792*f6dc9357SAndroid Build Coastguard Worker           for (; len2 < limit && data[len2] == data2[len2]; len2++)
1793*f6dc9357SAndroid Build Coastguard Worker           {}
1794*f6dc9357SAndroid Build Coastguard Worker 
1795*f6dc9357SAndroid Build Coastguard Worker           len2 -= len;
1796*f6dc9357SAndroid Build Coastguard Worker           // if (len2 >= 3)
1797*f6dc9357SAndroid Build Coastguard Worker           {
1798*f6dc9357SAndroid Build Coastguard Worker             {
1799*f6dc9357SAndroid Build Coastguard Worker               unsigned offset = cur + len + len2;
1800*f6dc9357SAndroid Build Coastguard Worker 
1801*f6dc9357SAndroid Build Coastguard Worker               if (last < offset)
1802*f6dc9357SAndroid Build Coastguard Worker                 last = offset;
1803*f6dc9357SAndroid Build Coastguard Worker               // do
1804*f6dc9357SAndroid Build Coastguard Worker               {
1805*f6dc9357SAndroid Build Coastguard Worker                 UInt32 price2;
1806*f6dc9357SAndroid Build Coastguard Worker                 COptimal *opt;
1807*f6dc9357SAndroid Build Coastguard Worker                 len2--;
1808*f6dc9357SAndroid Build Coastguard Worker                 // price2 = price + GetPrice_Len_Rep_0(p, len2, state2, posState2);
1809*f6dc9357SAndroid Build Coastguard Worker                 price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState2, len2);
1810*f6dc9357SAndroid Build Coastguard Worker 
1811*f6dc9357SAndroid Build Coastguard Worker                 opt = &p->opt[offset];
1812*f6dc9357SAndroid Build Coastguard Worker                 // offset--;
1813*f6dc9357SAndroid Build Coastguard Worker                 if (price2 < opt->price)
1814*f6dc9357SAndroid Build Coastguard Worker                 {
1815*f6dc9357SAndroid Build Coastguard Worker                   opt->price = price2;
1816*f6dc9357SAndroid Build Coastguard Worker                   opt->len = (UInt32)len2;
1817*f6dc9357SAndroid Build Coastguard Worker                   opt->extra = (CExtra)(len + 1);
1818*f6dc9357SAndroid Build Coastguard Worker                   opt->dist = (UInt32)repIndex;
1819*f6dc9357SAndroid Build Coastguard Worker                 }
1820*f6dc9357SAndroid Build Coastguard Worker               }
1821*f6dc9357SAndroid Build Coastguard Worker               // while (len2 >= 3);
1822*f6dc9357SAndroid Build Coastguard Worker             }
1823*f6dc9357SAndroid Build Coastguard Worker           }
1824*f6dc9357SAndroid Build Coastguard Worker           }
1825*f6dc9357SAndroid Build Coastguard Worker         }
1826*f6dc9357SAndroid Build Coastguard Worker       }
1827*f6dc9357SAndroid Build Coastguard Worker     }
1828*f6dc9357SAndroid Build Coastguard Worker 
1829*f6dc9357SAndroid Build Coastguard Worker 
1830*f6dc9357SAndroid Build Coastguard Worker     // ---------- MATCH ----------
1831*f6dc9357SAndroid Build Coastguard Worker     /* for (unsigned len = 2; len <= newLen; len++) */
1832*f6dc9357SAndroid Build Coastguard Worker     if (newLen > numAvail)
1833*f6dc9357SAndroid Build Coastguard Worker     {
1834*f6dc9357SAndroid Build Coastguard Worker       newLen = numAvail;
1835*f6dc9357SAndroid Build Coastguard Worker       for (numPairs = 0; newLen > MATCHES[numPairs]; numPairs += 2);
1836*f6dc9357SAndroid Build Coastguard Worker       MATCHES[numPairs] = (UInt32)newLen;
1837*f6dc9357SAndroid Build Coastguard Worker       numPairs += 2;
1838*f6dc9357SAndroid Build Coastguard Worker     }
1839*f6dc9357SAndroid Build Coastguard Worker 
1840*f6dc9357SAndroid Build Coastguard Worker     // startLen = 2; /* speed optimization */
1841*f6dc9357SAndroid Build Coastguard Worker 
1842*f6dc9357SAndroid Build Coastguard Worker     if (newLen >= startLen)
1843*f6dc9357SAndroid Build Coastguard Worker     {
1844*f6dc9357SAndroid Build Coastguard Worker       UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]);
1845*f6dc9357SAndroid Build Coastguard Worker       UInt32 dist;
1846*f6dc9357SAndroid Build Coastguard Worker       unsigned offs, posSlot, len;
1847*f6dc9357SAndroid Build Coastguard Worker 
1848*f6dc9357SAndroid Build Coastguard Worker       {
1849*f6dc9357SAndroid Build Coastguard Worker         unsigned offset = cur + newLen;
1850*f6dc9357SAndroid Build Coastguard Worker         if (last < offset)
1851*f6dc9357SAndroid Build Coastguard Worker           last = offset;
1852*f6dc9357SAndroid Build Coastguard Worker       }
1853*f6dc9357SAndroid Build Coastguard Worker 
1854*f6dc9357SAndroid Build Coastguard Worker       offs = 0;
1855*f6dc9357SAndroid Build Coastguard Worker       while (startLen > MATCHES[offs])
1856*f6dc9357SAndroid Build Coastguard Worker         offs += 2;
1857*f6dc9357SAndroid Build Coastguard Worker       dist = MATCHES[(size_t)offs + 1];
1858*f6dc9357SAndroid Build Coastguard Worker 
1859*f6dc9357SAndroid Build Coastguard Worker       // if (dist >= kNumFullDistances)
1860*f6dc9357SAndroid Build Coastguard Worker       GetPosSlot2(dist, posSlot)
1861*f6dc9357SAndroid Build Coastguard Worker 
1862*f6dc9357SAndroid Build Coastguard Worker       for (len = /*2*/ startLen; ; len++)
1863*f6dc9357SAndroid Build Coastguard Worker       {
1864*f6dc9357SAndroid Build Coastguard Worker         UInt32 price = normalMatchPrice + GET_PRICE_LEN(&p->lenEnc, posState, len);
1865*f6dc9357SAndroid Build Coastguard Worker         {
1866*f6dc9357SAndroid Build Coastguard Worker           COptimal *opt;
1867*f6dc9357SAndroid Build Coastguard Worker           unsigned lenNorm = len - 2;
1868*f6dc9357SAndroid Build Coastguard Worker           lenNorm = GetLenToPosState2(lenNorm);
1869*f6dc9357SAndroid Build Coastguard Worker           if (dist < kNumFullDistances)
1870*f6dc9357SAndroid Build Coastguard Worker             price += p->distancesPrices[lenNorm][dist & (kNumFullDistances - 1)];
1871*f6dc9357SAndroid Build Coastguard Worker           else
1872*f6dc9357SAndroid Build Coastguard Worker             price += p->posSlotPrices[lenNorm][posSlot] + p->alignPrices[dist & kAlignMask];
1873*f6dc9357SAndroid Build Coastguard Worker 
1874*f6dc9357SAndroid Build Coastguard Worker           opt = &p->opt[cur + len];
1875*f6dc9357SAndroid Build Coastguard Worker           if (price < opt->price)
1876*f6dc9357SAndroid Build Coastguard Worker           {
1877*f6dc9357SAndroid Build Coastguard Worker             opt->price = price;
1878*f6dc9357SAndroid Build Coastguard Worker             opt->len = (UInt32)len;
1879*f6dc9357SAndroid Build Coastguard Worker             opt->dist = dist + LZMA_NUM_REPS;
1880*f6dc9357SAndroid Build Coastguard Worker             opt->extra = 0;
1881*f6dc9357SAndroid Build Coastguard Worker           }
1882*f6dc9357SAndroid Build Coastguard Worker         }
1883*f6dc9357SAndroid Build Coastguard Worker 
1884*f6dc9357SAndroid Build Coastguard Worker         if (len == MATCHES[offs])
1885*f6dc9357SAndroid Build Coastguard Worker         {
1886*f6dc9357SAndroid Build Coastguard Worker           // if (p->_maxMode) {
1887*f6dc9357SAndroid Build Coastguard Worker           // MATCH : LIT : REP_0
1888*f6dc9357SAndroid Build Coastguard Worker 
1889*f6dc9357SAndroid Build Coastguard Worker           const Byte *data2 = data - dist - 1;
1890*f6dc9357SAndroid Build Coastguard Worker           unsigned len2 = len + 1;
1891*f6dc9357SAndroid Build Coastguard Worker           unsigned limit = len2 + p->numFastBytes;
1892*f6dc9357SAndroid Build Coastguard Worker           if (limit > numAvailFull)
1893*f6dc9357SAndroid Build Coastguard Worker             limit = numAvailFull;
1894*f6dc9357SAndroid Build Coastguard Worker 
1895*f6dc9357SAndroid Build Coastguard Worker           len2 += 2;
1896*f6dc9357SAndroid Build Coastguard Worker           if (len2 <= limit)
1897*f6dc9357SAndroid Build Coastguard Worker           if (data[len2 - 2] == data2[len2 - 2])
1898*f6dc9357SAndroid Build Coastguard Worker           if (data[len2 - 1] == data2[len2 - 1])
1899*f6dc9357SAndroid Build Coastguard Worker           {
1900*f6dc9357SAndroid Build Coastguard Worker           for (; len2 < limit && data[len2] == data2[len2]; len2++)
1901*f6dc9357SAndroid Build Coastguard Worker           {}
1902*f6dc9357SAndroid Build Coastguard Worker 
1903*f6dc9357SAndroid Build Coastguard Worker           len2 -= len;
1904*f6dc9357SAndroid Build Coastguard Worker 
1905*f6dc9357SAndroid Build Coastguard Worker           // if (len2 >= 3)
1906*f6dc9357SAndroid Build Coastguard Worker           {
1907*f6dc9357SAndroid Build Coastguard Worker             unsigned state2 = kMatchNextStates[state];
1908*f6dc9357SAndroid Build Coastguard Worker             unsigned posState2 = (position + len) & p->pbMask;
1909*f6dc9357SAndroid Build Coastguard Worker             unsigned offset;
1910*f6dc9357SAndroid Build Coastguard Worker             price += GET_PRICE_0(p->isMatch[state2][posState2]);
1911*f6dc9357SAndroid Build Coastguard Worker             price += LitEnc_Matched_GetPrice(LIT_PROBS(position + len, data[(size_t)len - 1]),
1912*f6dc9357SAndroid Build Coastguard Worker                     data[len], data2[len], p->ProbPrices);
1913*f6dc9357SAndroid Build Coastguard Worker 
1914*f6dc9357SAndroid Build Coastguard Worker             // state2 = kLiteralNextStates[state2];
1915*f6dc9357SAndroid Build Coastguard Worker             state2 = kState_LitAfterMatch;
1916*f6dc9357SAndroid Build Coastguard Worker 
1917*f6dc9357SAndroid Build Coastguard Worker             posState2 = (posState2 + 1) & p->pbMask;
1918*f6dc9357SAndroid Build Coastguard Worker             price += GetPrice_Rep_0(p, state2, posState2);
1919*f6dc9357SAndroid Build Coastguard Worker 
1920*f6dc9357SAndroid Build Coastguard Worker             offset = cur + len + len2;
1921*f6dc9357SAndroid Build Coastguard Worker 
1922*f6dc9357SAndroid Build Coastguard Worker             if (last < offset)
1923*f6dc9357SAndroid Build Coastguard Worker               last = offset;
1924*f6dc9357SAndroid Build Coastguard Worker             // do
1925*f6dc9357SAndroid Build Coastguard Worker             {
1926*f6dc9357SAndroid Build Coastguard Worker               UInt32 price2;
1927*f6dc9357SAndroid Build Coastguard Worker               COptimal *opt;
1928*f6dc9357SAndroid Build Coastguard Worker               len2--;
1929*f6dc9357SAndroid Build Coastguard Worker               // price2 = price + GetPrice_Len_Rep_0(p, len2, state2, posState2);
1930*f6dc9357SAndroid Build Coastguard Worker               price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState2, len2);
1931*f6dc9357SAndroid Build Coastguard Worker               opt = &p->opt[offset];
1932*f6dc9357SAndroid Build Coastguard Worker               // offset--;
1933*f6dc9357SAndroid Build Coastguard Worker               if (price2 < opt->price)
1934*f6dc9357SAndroid Build Coastguard Worker               {
1935*f6dc9357SAndroid Build Coastguard Worker                 opt->price = price2;
1936*f6dc9357SAndroid Build Coastguard Worker                 opt->len = (UInt32)len2;
1937*f6dc9357SAndroid Build Coastguard Worker                 opt->extra = (CExtra)(len + 1);
1938*f6dc9357SAndroid Build Coastguard Worker                 opt->dist = dist + LZMA_NUM_REPS;
1939*f6dc9357SAndroid Build Coastguard Worker               }
1940*f6dc9357SAndroid Build Coastguard Worker             }
1941*f6dc9357SAndroid Build Coastguard Worker             // while (len2 >= 3);
1942*f6dc9357SAndroid Build Coastguard Worker           }
1943*f6dc9357SAndroid Build Coastguard Worker 
1944*f6dc9357SAndroid Build Coastguard Worker           }
1945*f6dc9357SAndroid Build Coastguard Worker 
1946*f6dc9357SAndroid Build Coastguard Worker           offs += 2;
1947*f6dc9357SAndroid Build Coastguard Worker           if (offs == numPairs)
1948*f6dc9357SAndroid Build Coastguard Worker             break;
1949*f6dc9357SAndroid Build Coastguard Worker           dist = MATCHES[(size_t)offs + 1];
1950*f6dc9357SAndroid Build Coastguard Worker           // if (dist >= kNumFullDistances)
1951*f6dc9357SAndroid Build Coastguard Worker             GetPosSlot2(dist, posSlot)
1952*f6dc9357SAndroid Build Coastguard Worker         }
1953*f6dc9357SAndroid Build Coastguard Worker       }
1954*f6dc9357SAndroid Build Coastguard Worker     }
1955*f6dc9357SAndroid Build Coastguard Worker   }
1956*f6dc9357SAndroid Build Coastguard Worker 
1957*f6dc9357SAndroid Build Coastguard Worker   do
1958*f6dc9357SAndroid Build Coastguard Worker     p->opt[last].price = kInfinityPrice;
1959*f6dc9357SAndroid Build Coastguard Worker   while (--last);
1960*f6dc9357SAndroid Build Coastguard Worker 
1961*f6dc9357SAndroid Build Coastguard Worker   return Backward(p, cur);
1962*f6dc9357SAndroid Build Coastguard Worker }
1963*f6dc9357SAndroid Build Coastguard Worker 
1964*f6dc9357SAndroid Build Coastguard Worker 
1965*f6dc9357SAndroid Build Coastguard Worker 
1966*f6dc9357SAndroid Build Coastguard Worker #define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist))
1967*f6dc9357SAndroid Build Coastguard Worker 
1968*f6dc9357SAndroid Build Coastguard Worker 
1969*f6dc9357SAndroid Build Coastguard Worker 
GetOptimumFast(CLzmaEnc * p)1970*f6dc9357SAndroid Build Coastguard Worker static unsigned GetOptimumFast(CLzmaEnc *p)
1971*f6dc9357SAndroid Build Coastguard Worker {
1972*f6dc9357SAndroid Build Coastguard Worker   UInt32 numAvail, mainDist;
1973*f6dc9357SAndroid Build Coastguard Worker   unsigned mainLen, numPairs, repIndex, repLen, i;
1974*f6dc9357SAndroid Build Coastguard Worker   const Byte *data;
1975*f6dc9357SAndroid Build Coastguard Worker 
1976*f6dc9357SAndroid Build Coastguard Worker   if (p->additionalOffset == 0)
1977*f6dc9357SAndroid Build Coastguard Worker     mainLen = ReadMatchDistances(p, &numPairs);
1978*f6dc9357SAndroid Build Coastguard Worker   else
1979*f6dc9357SAndroid Build Coastguard Worker   {
1980*f6dc9357SAndroid Build Coastguard Worker     mainLen = p->longestMatchLen;
1981*f6dc9357SAndroid Build Coastguard Worker     numPairs = p->numPairs;
1982*f6dc9357SAndroid Build Coastguard Worker   }
1983*f6dc9357SAndroid Build Coastguard Worker 
1984*f6dc9357SAndroid Build Coastguard Worker   numAvail = p->numAvail;
1985*f6dc9357SAndroid Build Coastguard Worker   p->backRes = MARK_LIT;
1986*f6dc9357SAndroid Build Coastguard Worker   if (numAvail < 2)
1987*f6dc9357SAndroid Build Coastguard Worker     return 1;
1988*f6dc9357SAndroid Build Coastguard Worker   // if (mainLen < 2 && p->state == 0) return 1; // 18.06.notused
1989*f6dc9357SAndroid Build Coastguard Worker   if (numAvail > LZMA_MATCH_LEN_MAX)
1990*f6dc9357SAndroid Build Coastguard Worker     numAvail = LZMA_MATCH_LEN_MAX;
1991*f6dc9357SAndroid Build Coastguard Worker   data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
1992*f6dc9357SAndroid Build Coastguard Worker   repLen = repIndex = 0;
1993*f6dc9357SAndroid Build Coastguard Worker 
1994*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < LZMA_NUM_REPS; i++)
1995*f6dc9357SAndroid Build Coastguard Worker   {
1996*f6dc9357SAndroid Build Coastguard Worker     unsigned len;
1997*f6dc9357SAndroid Build Coastguard Worker     const Byte *data2 = data - p->reps[i];
1998*f6dc9357SAndroid Build Coastguard Worker     if (data[0] != data2[0] || data[1] != data2[1])
1999*f6dc9357SAndroid Build Coastguard Worker       continue;
2000*f6dc9357SAndroid Build Coastguard Worker     for (len = 2; len < numAvail && data[len] == data2[len]; len++)
2001*f6dc9357SAndroid Build Coastguard Worker     {}
2002*f6dc9357SAndroid Build Coastguard Worker     if (len >= p->numFastBytes)
2003*f6dc9357SAndroid Build Coastguard Worker     {
2004*f6dc9357SAndroid Build Coastguard Worker       p->backRes = (UInt32)i;
2005*f6dc9357SAndroid Build Coastguard Worker       MOVE_POS(p, len - 1)
2006*f6dc9357SAndroid Build Coastguard Worker       return len;
2007*f6dc9357SAndroid Build Coastguard Worker     }
2008*f6dc9357SAndroid Build Coastguard Worker     if (len > repLen)
2009*f6dc9357SAndroid Build Coastguard Worker     {
2010*f6dc9357SAndroid Build Coastguard Worker       repIndex = i;
2011*f6dc9357SAndroid Build Coastguard Worker       repLen = len;
2012*f6dc9357SAndroid Build Coastguard Worker     }
2013*f6dc9357SAndroid Build Coastguard Worker   }
2014*f6dc9357SAndroid Build Coastguard Worker 
2015*f6dc9357SAndroid Build Coastguard Worker   if (mainLen >= p->numFastBytes)
2016*f6dc9357SAndroid Build Coastguard Worker   {
2017*f6dc9357SAndroid Build Coastguard Worker     p->backRes = p->matches[(size_t)numPairs - 1] + LZMA_NUM_REPS;
2018*f6dc9357SAndroid Build Coastguard Worker     MOVE_POS(p, mainLen - 1)
2019*f6dc9357SAndroid Build Coastguard Worker     return mainLen;
2020*f6dc9357SAndroid Build Coastguard Worker   }
2021*f6dc9357SAndroid Build Coastguard Worker 
2022*f6dc9357SAndroid Build Coastguard Worker   mainDist = 0; /* for GCC */
2023*f6dc9357SAndroid Build Coastguard Worker 
2024*f6dc9357SAndroid Build Coastguard Worker   if (mainLen >= 2)
2025*f6dc9357SAndroid Build Coastguard Worker   {
2026*f6dc9357SAndroid Build Coastguard Worker     mainDist = p->matches[(size_t)numPairs - 1];
2027*f6dc9357SAndroid Build Coastguard Worker     while (numPairs > 2)
2028*f6dc9357SAndroid Build Coastguard Worker     {
2029*f6dc9357SAndroid Build Coastguard Worker       UInt32 dist2;
2030*f6dc9357SAndroid Build Coastguard Worker       if (mainLen != p->matches[(size_t)numPairs - 4] + 1)
2031*f6dc9357SAndroid Build Coastguard Worker         break;
2032*f6dc9357SAndroid Build Coastguard Worker       dist2 = p->matches[(size_t)numPairs - 3];
2033*f6dc9357SAndroid Build Coastguard Worker       if (!ChangePair(dist2, mainDist))
2034*f6dc9357SAndroid Build Coastguard Worker         break;
2035*f6dc9357SAndroid Build Coastguard Worker       numPairs -= 2;
2036*f6dc9357SAndroid Build Coastguard Worker       mainLen--;
2037*f6dc9357SAndroid Build Coastguard Worker       mainDist = dist2;
2038*f6dc9357SAndroid Build Coastguard Worker     }
2039*f6dc9357SAndroid Build Coastguard Worker     if (mainLen == 2 && mainDist >= 0x80)
2040*f6dc9357SAndroid Build Coastguard Worker       mainLen = 1;
2041*f6dc9357SAndroid Build Coastguard Worker   }
2042*f6dc9357SAndroid Build Coastguard Worker 
2043*f6dc9357SAndroid Build Coastguard Worker   if (repLen >= 2)
2044*f6dc9357SAndroid Build Coastguard Worker     if (    repLen + 1 >= mainLen
2045*f6dc9357SAndroid Build Coastguard Worker         || (repLen + 2 >= mainLen && mainDist >= (1 << 9))
2046*f6dc9357SAndroid Build Coastguard Worker         || (repLen + 3 >= mainLen && mainDist >= (1 << 15)))
2047*f6dc9357SAndroid Build Coastguard Worker   {
2048*f6dc9357SAndroid Build Coastguard Worker     p->backRes = (UInt32)repIndex;
2049*f6dc9357SAndroid Build Coastguard Worker     MOVE_POS(p, repLen - 1)
2050*f6dc9357SAndroid Build Coastguard Worker     return repLen;
2051*f6dc9357SAndroid Build Coastguard Worker   }
2052*f6dc9357SAndroid Build Coastguard Worker 
2053*f6dc9357SAndroid Build Coastguard Worker   if (mainLen < 2 || numAvail <= 2)
2054*f6dc9357SAndroid Build Coastguard Worker     return 1;
2055*f6dc9357SAndroid Build Coastguard Worker 
2056*f6dc9357SAndroid Build Coastguard Worker   {
2057*f6dc9357SAndroid Build Coastguard Worker     unsigned len1 = ReadMatchDistances(p, &p->numPairs);
2058*f6dc9357SAndroid Build Coastguard Worker     p->longestMatchLen = len1;
2059*f6dc9357SAndroid Build Coastguard Worker 
2060*f6dc9357SAndroid Build Coastguard Worker     if (len1 >= 2)
2061*f6dc9357SAndroid Build Coastguard Worker     {
2062*f6dc9357SAndroid Build Coastguard Worker       UInt32 newDist = p->matches[(size_t)p->numPairs - 1];
2063*f6dc9357SAndroid Build Coastguard Worker       if (   (len1 >= mainLen && newDist < mainDist)
2064*f6dc9357SAndroid Build Coastguard Worker           || (len1 == mainLen + 1 && !ChangePair(mainDist, newDist))
2065*f6dc9357SAndroid Build Coastguard Worker           || (len1 >  mainLen + 1)
2066*f6dc9357SAndroid Build Coastguard Worker           || (len1 + 1 >= mainLen && mainLen >= 3 && ChangePair(newDist, mainDist)))
2067*f6dc9357SAndroid Build Coastguard Worker         return 1;
2068*f6dc9357SAndroid Build Coastguard Worker     }
2069*f6dc9357SAndroid Build Coastguard Worker   }
2070*f6dc9357SAndroid Build Coastguard Worker 
2071*f6dc9357SAndroid Build Coastguard Worker   data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
2072*f6dc9357SAndroid Build Coastguard Worker 
2073*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < LZMA_NUM_REPS; i++)
2074*f6dc9357SAndroid Build Coastguard Worker   {
2075*f6dc9357SAndroid Build Coastguard Worker     unsigned len, limit;
2076*f6dc9357SAndroid Build Coastguard Worker     const Byte *data2 = data - p->reps[i];
2077*f6dc9357SAndroid Build Coastguard Worker     if (data[0] != data2[0] || data[1] != data2[1])
2078*f6dc9357SAndroid Build Coastguard Worker       continue;
2079*f6dc9357SAndroid Build Coastguard Worker     limit = mainLen - 1;
2080*f6dc9357SAndroid Build Coastguard Worker     for (len = 2;; len++)
2081*f6dc9357SAndroid Build Coastguard Worker     {
2082*f6dc9357SAndroid Build Coastguard Worker       if (len >= limit)
2083*f6dc9357SAndroid Build Coastguard Worker         return 1;
2084*f6dc9357SAndroid Build Coastguard Worker       if (data[len] != data2[len])
2085*f6dc9357SAndroid Build Coastguard Worker         break;
2086*f6dc9357SAndroid Build Coastguard Worker     }
2087*f6dc9357SAndroid Build Coastguard Worker   }
2088*f6dc9357SAndroid Build Coastguard Worker 
2089*f6dc9357SAndroid Build Coastguard Worker   p->backRes = mainDist + LZMA_NUM_REPS;
2090*f6dc9357SAndroid Build Coastguard Worker   if (mainLen != 2)
2091*f6dc9357SAndroid Build Coastguard Worker   {
2092*f6dc9357SAndroid Build Coastguard Worker     MOVE_POS(p, mainLen - 2)
2093*f6dc9357SAndroid Build Coastguard Worker   }
2094*f6dc9357SAndroid Build Coastguard Worker   return mainLen;
2095*f6dc9357SAndroid Build Coastguard Worker }
2096*f6dc9357SAndroid Build Coastguard Worker 
2097*f6dc9357SAndroid Build Coastguard Worker 
2098*f6dc9357SAndroid Build Coastguard Worker 
2099*f6dc9357SAndroid Build Coastguard Worker 
WriteEndMarker(CLzmaEnc * p,unsigned posState)2100*f6dc9357SAndroid Build Coastguard Worker static void WriteEndMarker(CLzmaEnc *p, unsigned posState)
2101*f6dc9357SAndroid Build Coastguard Worker {
2102*f6dc9357SAndroid Build Coastguard Worker   UInt32 range;
2103*f6dc9357SAndroid Build Coastguard Worker   range = p->rc.range;
2104*f6dc9357SAndroid Build Coastguard Worker   {
2105*f6dc9357SAndroid Build Coastguard Worker     UInt32 ttt, newBound;
2106*f6dc9357SAndroid Build Coastguard Worker     CLzmaProb *prob = &p->isMatch[p->state][posState];
2107*f6dc9357SAndroid Build Coastguard Worker     RC_BIT_PRE(&p->rc, prob)
2108*f6dc9357SAndroid Build Coastguard Worker     RC_BIT_1(&p->rc, prob)
2109*f6dc9357SAndroid Build Coastguard Worker     prob = &p->isRep[p->state];
2110*f6dc9357SAndroid Build Coastguard Worker     RC_BIT_PRE(&p->rc, prob)
2111*f6dc9357SAndroid Build Coastguard Worker     RC_BIT_0(&p->rc, prob)
2112*f6dc9357SAndroid Build Coastguard Worker   }
2113*f6dc9357SAndroid Build Coastguard Worker   p->state = kMatchNextStates[p->state];
2114*f6dc9357SAndroid Build Coastguard Worker 
2115*f6dc9357SAndroid Build Coastguard Worker   p->rc.range = range;
2116*f6dc9357SAndroid Build Coastguard Worker   LenEnc_Encode(&p->lenProbs, &p->rc, 0, posState);
2117*f6dc9357SAndroid Build Coastguard Worker   range = p->rc.range;
2118*f6dc9357SAndroid Build Coastguard Worker 
2119*f6dc9357SAndroid Build Coastguard Worker   {
2120*f6dc9357SAndroid Build Coastguard Worker     // RcTree_Encode_PosSlot(&p->rc, p->posSlotEncoder[0], (1 << kNumPosSlotBits) - 1);
2121*f6dc9357SAndroid Build Coastguard Worker     CLzmaProb *probs = p->posSlotEncoder[0];
2122*f6dc9357SAndroid Build Coastguard Worker     unsigned m = 1;
2123*f6dc9357SAndroid Build Coastguard Worker     do
2124*f6dc9357SAndroid Build Coastguard Worker     {
2125*f6dc9357SAndroid Build Coastguard Worker       UInt32 ttt, newBound;
2126*f6dc9357SAndroid Build Coastguard Worker       RC_BIT_PRE(p, probs + m)
2127*f6dc9357SAndroid Build Coastguard Worker       RC_BIT_1(&p->rc, probs + m)
2128*f6dc9357SAndroid Build Coastguard Worker       m = (m << 1) + 1;
2129*f6dc9357SAndroid Build Coastguard Worker     }
2130*f6dc9357SAndroid Build Coastguard Worker     while (m < (1 << kNumPosSlotBits));
2131*f6dc9357SAndroid Build Coastguard Worker   }
2132*f6dc9357SAndroid Build Coastguard Worker   {
2133*f6dc9357SAndroid Build Coastguard Worker     // RangeEnc_EncodeDirectBits(&p->rc, ((UInt32)1 << (30 - kNumAlignBits)) - 1, 30 - kNumAlignBits);    UInt32 range = p->range;
2134*f6dc9357SAndroid Build Coastguard Worker     unsigned numBits = 30 - kNumAlignBits;
2135*f6dc9357SAndroid Build Coastguard Worker     do
2136*f6dc9357SAndroid Build Coastguard Worker     {
2137*f6dc9357SAndroid Build Coastguard Worker       range >>= 1;
2138*f6dc9357SAndroid Build Coastguard Worker       p->rc.low += range;
2139*f6dc9357SAndroid Build Coastguard Worker       RC_NORM(&p->rc)
2140*f6dc9357SAndroid Build Coastguard Worker     }
2141*f6dc9357SAndroid Build Coastguard Worker     while (--numBits);
2142*f6dc9357SAndroid Build Coastguard Worker   }
2143*f6dc9357SAndroid Build Coastguard Worker 
2144*f6dc9357SAndroid Build Coastguard Worker   {
2145*f6dc9357SAndroid Build Coastguard Worker     // RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);
2146*f6dc9357SAndroid Build Coastguard Worker     CLzmaProb *probs = p->posAlignEncoder;
2147*f6dc9357SAndroid Build Coastguard Worker     unsigned m = 1;
2148*f6dc9357SAndroid Build Coastguard Worker     do
2149*f6dc9357SAndroid Build Coastguard Worker     {
2150*f6dc9357SAndroid Build Coastguard Worker       UInt32 ttt, newBound;
2151*f6dc9357SAndroid Build Coastguard Worker       RC_BIT_PRE(p, probs + m)
2152*f6dc9357SAndroid Build Coastguard Worker       RC_BIT_1(&p->rc, probs + m)
2153*f6dc9357SAndroid Build Coastguard Worker       m = (m << 1) + 1;
2154*f6dc9357SAndroid Build Coastguard Worker     }
2155*f6dc9357SAndroid Build Coastguard Worker     while (m < kAlignTableSize);
2156*f6dc9357SAndroid Build Coastguard Worker   }
2157*f6dc9357SAndroid Build Coastguard Worker   p->rc.range = range;
2158*f6dc9357SAndroid Build Coastguard Worker }
2159*f6dc9357SAndroid Build Coastguard Worker 
2160*f6dc9357SAndroid Build Coastguard Worker 
CheckErrors(CLzmaEnc * p)2161*f6dc9357SAndroid Build Coastguard Worker static SRes CheckErrors(CLzmaEnc *p)
2162*f6dc9357SAndroid Build Coastguard Worker {
2163*f6dc9357SAndroid Build Coastguard Worker   if (p->result != SZ_OK)
2164*f6dc9357SAndroid Build Coastguard Worker     return p->result;
2165*f6dc9357SAndroid Build Coastguard Worker   if (p->rc.res != SZ_OK)
2166*f6dc9357SAndroid Build Coastguard Worker     p->result = SZ_ERROR_WRITE;
2167*f6dc9357SAndroid Build Coastguard Worker 
2168*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
2169*f6dc9357SAndroid Build Coastguard Worker   if (
2170*f6dc9357SAndroid Build Coastguard Worker       // p->mf_Failure ||
2171*f6dc9357SAndroid Build Coastguard Worker         (p->mtMode &&
2172*f6dc9357SAndroid Build Coastguard Worker           ( // p->matchFinderMt.failure_LZ_LZ ||
2173*f6dc9357SAndroid Build Coastguard Worker             p->matchFinderMt.failure_LZ_BT))
2174*f6dc9357SAndroid Build Coastguard Worker      )
2175*f6dc9357SAndroid Build Coastguard Worker   {
2176*f6dc9357SAndroid Build Coastguard Worker     p->result = MY_HRES_ERROR_INTERNAL_ERROR;
2177*f6dc9357SAndroid Build Coastguard Worker     // printf("\nCheckErrors p->matchFinderMt.failureLZ\n");
2178*f6dc9357SAndroid Build Coastguard Worker   }
2179*f6dc9357SAndroid Build Coastguard Worker   #endif
2180*f6dc9357SAndroid Build Coastguard Worker 
2181*f6dc9357SAndroid Build Coastguard Worker   if (MFB.result != SZ_OK)
2182*f6dc9357SAndroid Build Coastguard Worker     p->result = SZ_ERROR_READ;
2183*f6dc9357SAndroid Build Coastguard Worker 
2184*f6dc9357SAndroid Build Coastguard Worker   if (p->result != SZ_OK)
2185*f6dc9357SAndroid Build Coastguard Worker     p->finished = True;
2186*f6dc9357SAndroid Build Coastguard Worker   return p->result;
2187*f6dc9357SAndroid Build Coastguard Worker }
2188*f6dc9357SAndroid Build Coastguard Worker 
2189*f6dc9357SAndroid Build Coastguard Worker 
Flush(CLzmaEnc * p,UInt32 nowPos)2190*f6dc9357SAndroid Build Coastguard Worker Z7_NO_INLINE static SRes Flush(CLzmaEnc *p, UInt32 nowPos)
2191*f6dc9357SAndroid Build Coastguard Worker {
2192*f6dc9357SAndroid Build Coastguard Worker   /* ReleaseMFStream(); */
2193*f6dc9357SAndroid Build Coastguard Worker   p->finished = True;
2194*f6dc9357SAndroid Build Coastguard Worker   if (p->writeEndMark)
2195*f6dc9357SAndroid Build Coastguard Worker     WriteEndMarker(p, nowPos & p->pbMask);
2196*f6dc9357SAndroid Build Coastguard Worker   RangeEnc_FlushData(&p->rc);
2197*f6dc9357SAndroid Build Coastguard Worker   RangeEnc_FlushStream(&p->rc);
2198*f6dc9357SAndroid Build Coastguard Worker   return CheckErrors(p);
2199*f6dc9357SAndroid Build Coastguard Worker }
2200*f6dc9357SAndroid Build Coastguard Worker 
2201*f6dc9357SAndroid Build Coastguard Worker 
FillAlignPrices(CLzmaEnc * p)2202*f6dc9357SAndroid Build Coastguard Worker Z7_NO_INLINE static void FillAlignPrices(CLzmaEnc *p)
2203*f6dc9357SAndroid Build Coastguard Worker {
2204*f6dc9357SAndroid Build Coastguard Worker   unsigned i;
2205*f6dc9357SAndroid Build Coastguard Worker   const CProbPrice *ProbPrices = p->ProbPrices;
2206*f6dc9357SAndroid Build Coastguard Worker   const CLzmaProb *probs = p->posAlignEncoder;
2207*f6dc9357SAndroid Build Coastguard Worker   // p->alignPriceCount = 0;
2208*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < kAlignTableSize / 2; i++)
2209*f6dc9357SAndroid Build Coastguard Worker   {
2210*f6dc9357SAndroid Build Coastguard Worker     UInt32 price = 0;
2211*f6dc9357SAndroid Build Coastguard Worker     unsigned sym = i;
2212*f6dc9357SAndroid Build Coastguard Worker     unsigned m = 1;
2213*f6dc9357SAndroid Build Coastguard Worker     unsigned bit;
2214*f6dc9357SAndroid Build Coastguard Worker     UInt32 prob;
2215*f6dc9357SAndroid Build Coastguard Worker     bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit;
2216*f6dc9357SAndroid Build Coastguard Worker     bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit;
2217*f6dc9357SAndroid Build Coastguard Worker     bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit;
2218*f6dc9357SAndroid Build Coastguard Worker     prob = probs[m];
2219*f6dc9357SAndroid Build Coastguard Worker     p->alignPrices[i    ] = price + GET_PRICEa_0(prob);
2220*f6dc9357SAndroid Build Coastguard Worker     p->alignPrices[i + 8] = price + GET_PRICEa_1(prob);
2221*f6dc9357SAndroid Build Coastguard Worker     // p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices);
2222*f6dc9357SAndroid Build Coastguard Worker   }
2223*f6dc9357SAndroid Build Coastguard Worker }
2224*f6dc9357SAndroid Build Coastguard Worker 
2225*f6dc9357SAndroid Build Coastguard Worker 
FillDistancesPrices(CLzmaEnc * p)2226*f6dc9357SAndroid Build Coastguard Worker Z7_NO_INLINE static void FillDistancesPrices(CLzmaEnc *p)
2227*f6dc9357SAndroid Build Coastguard Worker {
2228*f6dc9357SAndroid Build Coastguard Worker   // int y; for (y = 0; y < 100; y++) {
2229*f6dc9357SAndroid Build Coastguard Worker 
2230*f6dc9357SAndroid Build Coastguard Worker   UInt32 tempPrices[kNumFullDistances];
2231*f6dc9357SAndroid Build Coastguard Worker   unsigned i, lps;
2232*f6dc9357SAndroid Build Coastguard Worker 
2233*f6dc9357SAndroid Build Coastguard Worker   const CProbPrice *ProbPrices = p->ProbPrices;
2234*f6dc9357SAndroid Build Coastguard Worker   p->matchPriceCount = 0;
2235*f6dc9357SAndroid Build Coastguard Worker 
2236*f6dc9357SAndroid Build Coastguard Worker   for (i = kStartPosModelIndex / 2; i < kNumFullDistances / 2; i++)
2237*f6dc9357SAndroid Build Coastguard Worker   {
2238*f6dc9357SAndroid Build Coastguard Worker     unsigned posSlot = GetPosSlot1(i);
2239*f6dc9357SAndroid Build Coastguard Worker     unsigned footerBits = (posSlot >> 1) - 1;
2240*f6dc9357SAndroid Build Coastguard Worker     unsigned base = ((2 | (posSlot & 1)) << footerBits);
2241*f6dc9357SAndroid Build Coastguard Worker     const CLzmaProb *probs = p->posEncoders + (size_t)base * 2;
2242*f6dc9357SAndroid Build Coastguard Worker     // tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base, footerBits, i - base, p->ProbPrices);
2243*f6dc9357SAndroid Build Coastguard Worker     UInt32 price = 0;
2244*f6dc9357SAndroid Build Coastguard Worker     unsigned m = 1;
2245*f6dc9357SAndroid Build Coastguard Worker     unsigned sym = i;
2246*f6dc9357SAndroid Build Coastguard Worker     unsigned offset = (unsigned)1 << footerBits;
2247*f6dc9357SAndroid Build Coastguard Worker     base += i;
2248*f6dc9357SAndroid Build Coastguard Worker 
2249*f6dc9357SAndroid Build Coastguard Worker     if (footerBits)
2250*f6dc9357SAndroid Build Coastguard Worker     do
2251*f6dc9357SAndroid Build Coastguard Worker     {
2252*f6dc9357SAndroid Build Coastguard Worker       unsigned bit = sym & 1;
2253*f6dc9357SAndroid Build Coastguard Worker       sym >>= 1;
2254*f6dc9357SAndroid Build Coastguard Worker       price += GET_PRICEa(probs[m], bit);
2255*f6dc9357SAndroid Build Coastguard Worker       m = (m << 1) + bit;
2256*f6dc9357SAndroid Build Coastguard Worker     }
2257*f6dc9357SAndroid Build Coastguard Worker     while (--footerBits);
2258*f6dc9357SAndroid Build Coastguard Worker 
2259*f6dc9357SAndroid Build Coastguard Worker     {
2260*f6dc9357SAndroid Build Coastguard Worker       unsigned prob = probs[m];
2261*f6dc9357SAndroid Build Coastguard Worker       tempPrices[base         ] = price + GET_PRICEa_0(prob);
2262*f6dc9357SAndroid Build Coastguard Worker       tempPrices[base + offset] = price + GET_PRICEa_1(prob);
2263*f6dc9357SAndroid Build Coastguard Worker     }
2264*f6dc9357SAndroid Build Coastguard Worker   }
2265*f6dc9357SAndroid Build Coastguard Worker 
2266*f6dc9357SAndroid Build Coastguard Worker   for (lps = 0; lps < kNumLenToPosStates; lps++)
2267*f6dc9357SAndroid Build Coastguard Worker   {
2268*f6dc9357SAndroid Build Coastguard Worker     unsigned slot;
2269*f6dc9357SAndroid Build Coastguard Worker     unsigned distTableSize2 = (p->distTableSize + 1) >> 1;
2270*f6dc9357SAndroid Build Coastguard Worker     UInt32 *posSlotPrices = p->posSlotPrices[lps];
2271*f6dc9357SAndroid Build Coastguard Worker     const CLzmaProb *probs = p->posSlotEncoder[lps];
2272*f6dc9357SAndroid Build Coastguard Worker 
2273*f6dc9357SAndroid Build Coastguard Worker     for (slot = 0; slot < distTableSize2; slot++)
2274*f6dc9357SAndroid Build Coastguard Worker     {
2275*f6dc9357SAndroid Build Coastguard Worker       // posSlotPrices[slot] = RcTree_GetPrice(encoder, kNumPosSlotBits, slot, p->ProbPrices);
2276*f6dc9357SAndroid Build Coastguard Worker       UInt32 price;
2277*f6dc9357SAndroid Build Coastguard Worker       unsigned bit;
2278*f6dc9357SAndroid Build Coastguard Worker       unsigned sym = slot + (1 << (kNumPosSlotBits - 1));
2279*f6dc9357SAndroid Build Coastguard Worker       unsigned prob;
2280*f6dc9357SAndroid Build Coastguard Worker       bit = sym & 1; sym >>= 1; price  = GET_PRICEa(probs[sym], bit);
2281*f6dc9357SAndroid Build Coastguard Worker       bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit);
2282*f6dc9357SAndroid Build Coastguard Worker       bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit);
2283*f6dc9357SAndroid Build Coastguard Worker       bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit);
2284*f6dc9357SAndroid Build Coastguard Worker       bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit);
2285*f6dc9357SAndroid Build Coastguard Worker       prob = probs[(size_t)slot + (1 << (kNumPosSlotBits - 1))];
2286*f6dc9357SAndroid Build Coastguard Worker       posSlotPrices[(size_t)slot * 2    ] = price + GET_PRICEa_0(prob);
2287*f6dc9357SAndroid Build Coastguard Worker       posSlotPrices[(size_t)slot * 2 + 1] = price + GET_PRICEa_1(prob);
2288*f6dc9357SAndroid Build Coastguard Worker     }
2289*f6dc9357SAndroid Build Coastguard Worker 
2290*f6dc9357SAndroid Build Coastguard Worker     {
2291*f6dc9357SAndroid Build Coastguard Worker       UInt32 delta = ((UInt32)((kEndPosModelIndex / 2 - 1) - kNumAlignBits) << kNumBitPriceShiftBits);
2292*f6dc9357SAndroid Build Coastguard Worker       for (slot = kEndPosModelIndex / 2; slot < distTableSize2; slot++)
2293*f6dc9357SAndroid Build Coastguard Worker       {
2294*f6dc9357SAndroid Build Coastguard Worker         posSlotPrices[(size_t)slot * 2    ] += delta;
2295*f6dc9357SAndroid Build Coastguard Worker         posSlotPrices[(size_t)slot * 2 + 1] += delta;
2296*f6dc9357SAndroid Build Coastguard Worker         delta += ((UInt32)1 << kNumBitPriceShiftBits);
2297*f6dc9357SAndroid Build Coastguard Worker       }
2298*f6dc9357SAndroid Build Coastguard Worker     }
2299*f6dc9357SAndroid Build Coastguard Worker 
2300*f6dc9357SAndroid Build Coastguard Worker     {
2301*f6dc9357SAndroid Build Coastguard Worker       UInt32 *dp = p->distancesPrices[lps];
2302*f6dc9357SAndroid Build Coastguard Worker 
2303*f6dc9357SAndroid Build Coastguard Worker       dp[0] = posSlotPrices[0];
2304*f6dc9357SAndroid Build Coastguard Worker       dp[1] = posSlotPrices[1];
2305*f6dc9357SAndroid Build Coastguard Worker       dp[2] = posSlotPrices[2];
2306*f6dc9357SAndroid Build Coastguard Worker       dp[3] = posSlotPrices[3];
2307*f6dc9357SAndroid Build Coastguard Worker 
2308*f6dc9357SAndroid Build Coastguard Worker       for (i = 4; i < kNumFullDistances; i += 2)
2309*f6dc9357SAndroid Build Coastguard Worker       {
2310*f6dc9357SAndroid Build Coastguard Worker         UInt32 slotPrice = posSlotPrices[GetPosSlot1(i)];
2311*f6dc9357SAndroid Build Coastguard Worker         dp[i    ] = slotPrice + tempPrices[i];
2312*f6dc9357SAndroid Build Coastguard Worker         dp[i + 1] = slotPrice + tempPrices[i + 1];
2313*f6dc9357SAndroid Build Coastguard Worker       }
2314*f6dc9357SAndroid Build Coastguard Worker     }
2315*f6dc9357SAndroid Build Coastguard Worker   }
2316*f6dc9357SAndroid Build Coastguard Worker   // }
2317*f6dc9357SAndroid Build Coastguard Worker }
2318*f6dc9357SAndroid Build Coastguard Worker 
2319*f6dc9357SAndroid Build Coastguard Worker 
2320*f6dc9357SAndroid Build Coastguard Worker 
LzmaEnc_Construct(CLzmaEnc * p)2321*f6dc9357SAndroid Build Coastguard Worker static void LzmaEnc_Construct(CLzmaEnc *p)
2322*f6dc9357SAndroid Build Coastguard Worker {
2323*f6dc9357SAndroid Build Coastguard Worker   RangeEnc_Construct(&p->rc);
2324*f6dc9357SAndroid Build Coastguard Worker   MatchFinder_Construct(&MFB);
2325*f6dc9357SAndroid Build Coastguard Worker 
2326*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
2327*f6dc9357SAndroid Build Coastguard Worker   p->matchFinderMt.MatchFinder = &MFB;
2328*f6dc9357SAndroid Build Coastguard Worker   MatchFinderMt_Construct(&p->matchFinderMt);
2329*f6dc9357SAndroid Build Coastguard Worker   #endif
2330*f6dc9357SAndroid Build Coastguard Worker 
2331*f6dc9357SAndroid Build Coastguard Worker   {
2332*f6dc9357SAndroid Build Coastguard Worker     CLzmaEncProps props;
2333*f6dc9357SAndroid Build Coastguard Worker     LzmaEncProps_Init(&props);
2334*f6dc9357SAndroid Build Coastguard Worker     LzmaEnc_SetProps((CLzmaEncHandle)(void *)p, &props);
2335*f6dc9357SAndroid Build Coastguard Worker   }
2336*f6dc9357SAndroid Build Coastguard Worker 
2337*f6dc9357SAndroid Build Coastguard Worker   #ifndef LZMA_LOG_BSR
2338*f6dc9357SAndroid Build Coastguard Worker   LzmaEnc_FastPosInit(p->g_FastPos);
2339*f6dc9357SAndroid Build Coastguard Worker   #endif
2340*f6dc9357SAndroid Build Coastguard Worker 
2341*f6dc9357SAndroid Build Coastguard Worker   LzmaEnc_InitPriceTables(p->ProbPrices);
2342*f6dc9357SAndroid Build Coastguard Worker   p->litProbs = NULL;
2343*f6dc9357SAndroid Build Coastguard Worker   p->saveState.litProbs = NULL;
2344*f6dc9357SAndroid Build Coastguard Worker }
2345*f6dc9357SAndroid Build Coastguard Worker 
LzmaEnc_Create(ISzAllocPtr alloc)2346*f6dc9357SAndroid Build Coastguard Worker CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc)
2347*f6dc9357SAndroid Build Coastguard Worker {
2348*f6dc9357SAndroid Build Coastguard Worker   void *p;
2349*f6dc9357SAndroid Build Coastguard Worker   p = ISzAlloc_Alloc(alloc, sizeof(CLzmaEnc));
2350*f6dc9357SAndroid Build Coastguard Worker   if (p)
2351*f6dc9357SAndroid Build Coastguard Worker     LzmaEnc_Construct((CLzmaEnc *)p);
2352*f6dc9357SAndroid Build Coastguard Worker   return p;
2353*f6dc9357SAndroid Build Coastguard Worker }
2354*f6dc9357SAndroid Build Coastguard Worker 
LzmaEnc_FreeLits(CLzmaEnc * p,ISzAllocPtr alloc)2355*f6dc9357SAndroid Build Coastguard Worker static void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAllocPtr alloc)
2356*f6dc9357SAndroid Build Coastguard Worker {
2357*f6dc9357SAndroid Build Coastguard Worker   ISzAlloc_Free(alloc, p->litProbs);
2358*f6dc9357SAndroid Build Coastguard Worker   ISzAlloc_Free(alloc, p->saveState.litProbs);
2359*f6dc9357SAndroid Build Coastguard Worker   p->litProbs = NULL;
2360*f6dc9357SAndroid Build Coastguard Worker   p->saveState.litProbs = NULL;
2361*f6dc9357SAndroid Build Coastguard Worker }
2362*f6dc9357SAndroid Build Coastguard Worker 
LzmaEnc_Destruct(CLzmaEnc * p,ISzAllocPtr alloc,ISzAllocPtr allocBig)2363*f6dc9357SAndroid Build Coastguard Worker static void LzmaEnc_Destruct(CLzmaEnc *p, ISzAllocPtr alloc, ISzAllocPtr allocBig)
2364*f6dc9357SAndroid Build Coastguard Worker {
2365*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
2366*f6dc9357SAndroid Build Coastguard Worker   MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
2367*f6dc9357SAndroid Build Coastguard Worker   #endif
2368*f6dc9357SAndroid Build Coastguard Worker 
2369*f6dc9357SAndroid Build Coastguard Worker   MatchFinder_Free(&MFB, allocBig);
2370*f6dc9357SAndroid Build Coastguard Worker   LzmaEnc_FreeLits(p, alloc);
2371*f6dc9357SAndroid Build Coastguard Worker   RangeEnc_Free(&p->rc, alloc);
2372*f6dc9357SAndroid Build Coastguard Worker }
2373*f6dc9357SAndroid Build Coastguard Worker 
LzmaEnc_Destroy(CLzmaEncHandle p,ISzAllocPtr alloc,ISzAllocPtr allocBig)2374*f6dc9357SAndroid Build Coastguard Worker void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig)
2375*f6dc9357SAndroid Build Coastguard Worker {
2376*f6dc9357SAndroid Build Coastguard Worker   // GET_CLzmaEnc_p
2377*f6dc9357SAndroid Build Coastguard Worker   LzmaEnc_Destruct(p, alloc, allocBig);
2378*f6dc9357SAndroid Build Coastguard Worker   ISzAlloc_Free(alloc, p);
2379*f6dc9357SAndroid Build Coastguard Worker }
2380*f6dc9357SAndroid Build Coastguard Worker 
2381*f6dc9357SAndroid Build Coastguard Worker 
2382*f6dc9357SAndroid Build Coastguard Worker Z7_NO_INLINE
LzmaEnc_CodeOneBlock(CLzmaEnc * p,UInt32 maxPackSize,UInt32 maxUnpackSize)2383*f6dc9357SAndroid Build Coastguard Worker static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, UInt32 maxPackSize, UInt32 maxUnpackSize)
2384*f6dc9357SAndroid Build Coastguard Worker {
2385*f6dc9357SAndroid Build Coastguard Worker   UInt32 nowPos32, startPos32;
2386*f6dc9357SAndroid Build Coastguard Worker   if (p->needInit)
2387*f6dc9357SAndroid Build Coastguard Worker   {
2388*f6dc9357SAndroid Build Coastguard Worker     #ifndef Z7_ST
2389*f6dc9357SAndroid Build Coastguard Worker     if (p->mtMode)
2390*f6dc9357SAndroid Build Coastguard Worker     {
2391*f6dc9357SAndroid Build Coastguard Worker       RINOK(MatchFinderMt_InitMt(&p->matchFinderMt))
2392*f6dc9357SAndroid Build Coastguard Worker     }
2393*f6dc9357SAndroid Build Coastguard Worker     #endif
2394*f6dc9357SAndroid Build Coastguard Worker     p->matchFinder.Init(p->matchFinderObj);
2395*f6dc9357SAndroid Build Coastguard Worker     p->needInit = 0;
2396*f6dc9357SAndroid Build Coastguard Worker   }
2397*f6dc9357SAndroid Build Coastguard Worker 
2398*f6dc9357SAndroid Build Coastguard Worker   if (p->finished)
2399*f6dc9357SAndroid Build Coastguard Worker     return p->result;
2400*f6dc9357SAndroid Build Coastguard Worker   RINOK(CheckErrors(p))
2401*f6dc9357SAndroid Build Coastguard Worker 
2402*f6dc9357SAndroid Build Coastguard Worker   nowPos32 = (UInt32)p->nowPos64;
2403*f6dc9357SAndroid Build Coastguard Worker   startPos32 = nowPos32;
2404*f6dc9357SAndroid Build Coastguard Worker 
2405*f6dc9357SAndroid Build Coastguard Worker   if (p->nowPos64 == 0)
2406*f6dc9357SAndroid Build Coastguard Worker   {
2407*f6dc9357SAndroid Build Coastguard Worker     unsigned numPairs;
2408*f6dc9357SAndroid Build Coastguard Worker     Byte curByte;
2409*f6dc9357SAndroid Build Coastguard Worker     if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
2410*f6dc9357SAndroid Build Coastguard Worker       return Flush(p, nowPos32);
2411*f6dc9357SAndroid Build Coastguard Worker     ReadMatchDistances(p, &numPairs);
2412*f6dc9357SAndroid Build Coastguard Worker     RangeEnc_EncodeBit_0(&p->rc, &p->isMatch[kState_Start][0]);
2413*f6dc9357SAndroid Build Coastguard Worker     // p->state = kLiteralNextStates[p->state];
2414*f6dc9357SAndroid Build Coastguard Worker     curByte = *(p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset);
2415*f6dc9357SAndroid Build Coastguard Worker     LitEnc_Encode(&p->rc, p->litProbs, curByte);
2416*f6dc9357SAndroid Build Coastguard Worker     p->additionalOffset--;
2417*f6dc9357SAndroid Build Coastguard Worker     nowPos32++;
2418*f6dc9357SAndroid Build Coastguard Worker   }
2419*f6dc9357SAndroid Build Coastguard Worker 
2420*f6dc9357SAndroid Build Coastguard Worker   if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0)
2421*f6dc9357SAndroid Build Coastguard Worker 
2422*f6dc9357SAndroid Build Coastguard Worker   for (;;)
2423*f6dc9357SAndroid Build Coastguard Worker   {
2424*f6dc9357SAndroid Build Coastguard Worker     UInt32 dist;
2425*f6dc9357SAndroid Build Coastguard Worker     unsigned len, posState;
2426*f6dc9357SAndroid Build Coastguard Worker     UInt32 range, ttt, newBound;
2427*f6dc9357SAndroid Build Coastguard Worker     CLzmaProb *probs;
2428*f6dc9357SAndroid Build Coastguard Worker 
2429*f6dc9357SAndroid Build Coastguard Worker     if (p->fastMode)
2430*f6dc9357SAndroid Build Coastguard Worker       len = GetOptimumFast(p);
2431*f6dc9357SAndroid Build Coastguard Worker     else
2432*f6dc9357SAndroid Build Coastguard Worker     {
2433*f6dc9357SAndroid Build Coastguard Worker       unsigned oci = p->optCur;
2434*f6dc9357SAndroid Build Coastguard Worker       if (p->optEnd == oci)
2435*f6dc9357SAndroid Build Coastguard Worker         len = GetOptimum(p, nowPos32);
2436*f6dc9357SAndroid Build Coastguard Worker       else
2437*f6dc9357SAndroid Build Coastguard Worker       {
2438*f6dc9357SAndroid Build Coastguard Worker         const COptimal *opt = &p->opt[oci];
2439*f6dc9357SAndroid Build Coastguard Worker         len = opt->len;
2440*f6dc9357SAndroid Build Coastguard Worker         p->backRes = opt->dist;
2441*f6dc9357SAndroid Build Coastguard Worker         p->optCur = oci + 1;
2442*f6dc9357SAndroid Build Coastguard Worker       }
2443*f6dc9357SAndroid Build Coastguard Worker     }
2444*f6dc9357SAndroid Build Coastguard Worker 
2445*f6dc9357SAndroid Build Coastguard Worker     posState = (unsigned)nowPos32 & p->pbMask;
2446*f6dc9357SAndroid Build Coastguard Worker     range = p->rc.range;
2447*f6dc9357SAndroid Build Coastguard Worker     probs = &p->isMatch[p->state][posState];
2448*f6dc9357SAndroid Build Coastguard Worker 
2449*f6dc9357SAndroid Build Coastguard Worker     RC_BIT_PRE(&p->rc, probs)
2450*f6dc9357SAndroid Build Coastguard Worker 
2451*f6dc9357SAndroid Build Coastguard Worker     dist = p->backRes;
2452*f6dc9357SAndroid Build Coastguard Worker 
2453*f6dc9357SAndroid Build Coastguard Worker     #ifdef SHOW_STAT2
2454*f6dc9357SAndroid Build Coastguard Worker     printf("\n pos = %6X, len = %3u  pos = %6u", nowPos32, len, dist);
2455*f6dc9357SAndroid Build Coastguard Worker     #endif
2456*f6dc9357SAndroid Build Coastguard Worker 
2457*f6dc9357SAndroid Build Coastguard Worker     if (dist == MARK_LIT)
2458*f6dc9357SAndroid Build Coastguard Worker     {
2459*f6dc9357SAndroid Build Coastguard Worker       Byte curByte;
2460*f6dc9357SAndroid Build Coastguard Worker       const Byte *data;
2461*f6dc9357SAndroid Build Coastguard Worker       unsigned state;
2462*f6dc9357SAndroid Build Coastguard Worker 
2463*f6dc9357SAndroid Build Coastguard Worker       RC_BIT_0(&p->rc, probs)
2464*f6dc9357SAndroid Build Coastguard Worker       p->rc.range = range;
2465*f6dc9357SAndroid Build Coastguard Worker       data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
2466*f6dc9357SAndroid Build Coastguard Worker       probs = LIT_PROBS(nowPos32, *(data - 1));
2467*f6dc9357SAndroid Build Coastguard Worker       curByte = *data;
2468*f6dc9357SAndroid Build Coastguard Worker       state = p->state;
2469*f6dc9357SAndroid Build Coastguard Worker       p->state = kLiteralNextStates[state];
2470*f6dc9357SAndroid Build Coastguard Worker       if (IsLitState(state))
2471*f6dc9357SAndroid Build Coastguard Worker         LitEnc_Encode(&p->rc, probs, curByte);
2472*f6dc9357SAndroid Build Coastguard Worker       else
2473*f6dc9357SAndroid Build Coastguard Worker         LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0]));
2474*f6dc9357SAndroid Build Coastguard Worker     }
2475*f6dc9357SAndroid Build Coastguard Worker     else
2476*f6dc9357SAndroid Build Coastguard Worker     {
2477*f6dc9357SAndroid Build Coastguard Worker       RC_BIT_1(&p->rc, probs)
2478*f6dc9357SAndroid Build Coastguard Worker       probs = &p->isRep[p->state];
2479*f6dc9357SAndroid Build Coastguard Worker       RC_BIT_PRE(&p->rc, probs)
2480*f6dc9357SAndroid Build Coastguard Worker 
2481*f6dc9357SAndroid Build Coastguard Worker       if (dist < LZMA_NUM_REPS)
2482*f6dc9357SAndroid Build Coastguard Worker       {
2483*f6dc9357SAndroid Build Coastguard Worker         RC_BIT_1(&p->rc, probs)
2484*f6dc9357SAndroid Build Coastguard Worker         probs = &p->isRepG0[p->state];
2485*f6dc9357SAndroid Build Coastguard Worker         RC_BIT_PRE(&p->rc, probs)
2486*f6dc9357SAndroid Build Coastguard Worker         if (dist == 0)
2487*f6dc9357SAndroid Build Coastguard Worker         {
2488*f6dc9357SAndroid Build Coastguard Worker           RC_BIT_0(&p->rc, probs)
2489*f6dc9357SAndroid Build Coastguard Worker           probs = &p->isRep0Long[p->state][posState];
2490*f6dc9357SAndroid Build Coastguard Worker           RC_BIT_PRE(&p->rc, probs)
2491*f6dc9357SAndroid Build Coastguard Worker           if (len != 1)
2492*f6dc9357SAndroid Build Coastguard Worker           {
2493*f6dc9357SAndroid Build Coastguard Worker             RC_BIT_1_BASE(&p->rc, probs)
2494*f6dc9357SAndroid Build Coastguard Worker           }
2495*f6dc9357SAndroid Build Coastguard Worker           else
2496*f6dc9357SAndroid Build Coastguard Worker           {
2497*f6dc9357SAndroid Build Coastguard Worker             RC_BIT_0_BASE(&p->rc, probs)
2498*f6dc9357SAndroid Build Coastguard Worker             p->state = kShortRepNextStates[p->state];
2499*f6dc9357SAndroid Build Coastguard Worker           }
2500*f6dc9357SAndroid Build Coastguard Worker         }
2501*f6dc9357SAndroid Build Coastguard Worker         else
2502*f6dc9357SAndroid Build Coastguard Worker         {
2503*f6dc9357SAndroid Build Coastguard Worker           RC_BIT_1(&p->rc, probs)
2504*f6dc9357SAndroid Build Coastguard Worker           probs = &p->isRepG1[p->state];
2505*f6dc9357SAndroid Build Coastguard Worker           RC_BIT_PRE(&p->rc, probs)
2506*f6dc9357SAndroid Build Coastguard Worker           if (dist == 1)
2507*f6dc9357SAndroid Build Coastguard Worker           {
2508*f6dc9357SAndroid Build Coastguard Worker             RC_BIT_0_BASE(&p->rc, probs)
2509*f6dc9357SAndroid Build Coastguard Worker             dist = p->reps[1];
2510*f6dc9357SAndroid Build Coastguard Worker           }
2511*f6dc9357SAndroid Build Coastguard Worker           else
2512*f6dc9357SAndroid Build Coastguard Worker           {
2513*f6dc9357SAndroid Build Coastguard Worker             RC_BIT_1(&p->rc, probs)
2514*f6dc9357SAndroid Build Coastguard Worker             probs = &p->isRepG2[p->state];
2515*f6dc9357SAndroid Build Coastguard Worker             RC_BIT_PRE(&p->rc, probs)
2516*f6dc9357SAndroid Build Coastguard Worker             if (dist == 2)
2517*f6dc9357SAndroid Build Coastguard Worker             {
2518*f6dc9357SAndroid Build Coastguard Worker               RC_BIT_0_BASE(&p->rc, probs)
2519*f6dc9357SAndroid Build Coastguard Worker               dist = p->reps[2];
2520*f6dc9357SAndroid Build Coastguard Worker             }
2521*f6dc9357SAndroid Build Coastguard Worker             else
2522*f6dc9357SAndroid Build Coastguard Worker             {
2523*f6dc9357SAndroid Build Coastguard Worker               RC_BIT_1_BASE(&p->rc, probs)
2524*f6dc9357SAndroid Build Coastguard Worker               dist = p->reps[3];
2525*f6dc9357SAndroid Build Coastguard Worker               p->reps[3] = p->reps[2];
2526*f6dc9357SAndroid Build Coastguard Worker             }
2527*f6dc9357SAndroid Build Coastguard Worker             p->reps[2] = p->reps[1];
2528*f6dc9357SAndroid Build Coastguard Worker           }
2529*f6dc9357SAndroid Build Coastguard Worker           p->reps[1] = p->reps[0];
2530*f6dc9357SAndroid Build Coastguard Worker           p->reps[0] = dist;
2531*f6dc9357SAndroid Build Coastguard Worker         }
2532*f6dc9357SAndroid Build Coastguard Worker 
2533*f6dc9357SAndroid Build Coastguard Worker         RC_NORM(&p->rc)
2534*f6dc9357SAndroid Build Coastguard Worker 
2535*f6dc9357SAndroid Build Coastguard Worker         p->rc.range = range;
2536*f6dc9357SAndroid Build Coastguard Worker 
2537*f6dc9357SAndroid Build Coastguard Worker         if (len != 1)
2538*f6dc9357SAndroid Build Coastguard Worker         {
2539*f6dc9357SAndroid Build Coastguard Worker           LenEnc_Encode(&p->repLenProbs, &p->rc, len - LZMA_MATCH_LEN_MIN, posState);
2540*f6dc9357SAndroid Build Coastguard Worker           --p->repLenEncCounter;
2541*f6dc9357SAndroid Build Coastguard Worker           p->state = kRepNextStates[p->state];
2542*f6dc9357SAndroid Build Coastguard Worker         }
2543*f6dc9357SAndroid Build Coastguard Worker       }
2544*f6dc9357SAndroid Build Coastguard Worker       else
2545*f6dc9357SAndroid Build Coastguard Worker       {
2546*f6dc9357SAndroid Build Coastguard Worker         unsigned posSlot;
2547*f6dc9357SAndroid Build Coastguard Worker         RC_BIT_0(&p->rc, probs)
2548*f6dc9357SAndroid Build Coastguard Worker         p->rc.range = range;
2549*f6dc9357SAndroid Build Coastguard Worker         p->state = kMatchNextStates[p->state];
2550*f6dc9357SAndroid Build Coastguard Worker 
2551*f6dc9357SAndroid Build Coastguard Worker         LenEnc_Encode(&p->lenProbs, &p->rc, len - LZMA_MATCH_LEN_MIN, posState);
2552*f6dc9357SAndroid Build Coastguard Worker         // --p->lenEnc.counter;
2553*f6dc9357SAndroid Build Coastguard Worker 
2554*f6dc9357SAndroid Build Coastguard Worker         dist -= LZMA_NUM_REPS;
2555*f6dc9357SAndroid Build Coastguard Worker         p->reps[3] = p->reps[2];
2556*f6dc9357SAndroid Build Coastguard Worker         p->reps[2] = p->reps[1];
2557*f6dc9357SAndroid Build Coastguard Worker         p->reps[1] = p->reps[0];
2558*f6dc9357SAndroid Build Coastguard Worker         p->reps[0] = dist + 1;
2559*f6dc9357SAndroid Build Coastguard Worker 
2560*f6dc9357SAndroid Build Coastguard Worker         p->matchPriceCount++;
2561*f6dc9357SAndroid Build Coastguard Worker         GetPosSlot(dist, posSlot)
2562*f6dc9357SAndroid Build Coastguard Worker         // RcTree_Encode_PosSlot(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], posSlot);
2563*f6dc9357SAndroid Build Coastguard Worker         {
2564*f6dc9357SAndroid Build Coastguard Worker           UInt32 sym = (UInt32)posSlot + (1 << kNumPosSlotBits);
2565*f6dc9357SAndroid Build Coastguard Worker           range = p->rc.range;
2566*f6dc9357SAndroid Build Coastguard Worker           probs = p->posSlotEncoder[GetLenToPosState(len)];
2567*f6dc9357SAndroid Build Coastguard Worker           do
2568*f6dc9357SAndroid Build Coastguard Worker           {
2569*f6dc9357SAndroid Build Coastguard Worker             CLzmaProb *prob = probs + (sym >> kNumPosSlotBits);
2570*f6dc9357SAndroid Build Coastguard Worker             UInt32 bit = (sym >> (kNumPosSlotBits - 1)) & 1;
2571*f6dc9357SAndroid Build Coastguard Worker             sym <<= 1;
2572*f6dc9357SAndroid Build Coastguard Worker             RC_BIT(&p->rc, prob, bit)
2573*f6dc9357SAndroid Build Coastguard Worker           }
2574*f6dc9357SAndroid Build Coastguard Worker           while (sym < (1 << kNumPosSlotBits * 2));
2575*f6dc9357SAndroid Build Coastguard Worker           p->rc.range = range;
2576*f6dc9357SAndroid Build Coastguard Worker         }
2577*f6dc9357SAndroid Build Coastguard Worker 
2578*f6dc9357SAndroid Build Coastguard Worker         if (dist >= kStartPosModelIndex)
2579*f6dc9357SAndroid Build Coastguard Worker         {
2580*f6dc9357SAndroid Build Coastguard Worker           unsigned footerBits = ((posSlot >> 1) - 1);
2581*f6dc9357SAndroid Build Coastguard Worker 
2582*f6dc9357SAndroid Build Coastguard Worker           if (dist < kNumFullDistances)
2583*f6dc9357SAndroid Build Coastguard Worker           {
2584*f6dc9357SAndroid Build Coastguard Worker             unsigned base = ((2 | (posSlot & 1)) << footerBits);
2585*f6dc9357SAndroid Build Coastguard Worker             RcTree_ReverseEncode(&p->rc, p->posEncoders + base, footerBits, (unsigned)(dist /* - base */));
2586*f6dc9357SAndroid Build Coastguard Worker           }
2587*f6dc9357SAndroid Build Coastguard Worker           else
2588*f6dc9357SAndroid Build Coastguard Worker           {
2589*f6dc9357SAndroid Build Coastguard Worker             UInt32 pos2 = (dist | 0xF) << (32 - footerBits);
2590*f6dc9357SAndroid Build Coastguard Worker             range = p->rc.range;
2591*f6dc9357SAndroid Build Coastguard Worker             // RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
2592*f6dc9357SAndroid Build Coastguard Worker             /*
2593*f6dc9357SAndroid Build Coastguard Worker             do
2594*f6dc9357SAndroid Build Coastguard Worker             {
2595*f6dc9357SAndroid Build Coastguard Worker               range >>= 1;
2596*f6dc9357SAndroid Build Coastguard Worker               p->rc.low += range & (0 - ((dist >> --footerBits) & 1));
2597*f6dc9357SAndroid Build Coastguard Worker               RC_NORM(&p->rc)
2598*f6dc9357SAndroid Build Coastguard Worker             }
2599*f6dc9357SAndroid Build Coastguard Worker             while (footerBits > kNumAlignBits);
2600*f6dc9357SAndroid Build Coastguard Worker             */
2601*f6dc9357SAndroid Build Coastguard Worker             do
2602*f6dc9357SAndroid Build Coastguard Worker             {
2603*f6dc9357SAndroid Build Coastguard Worker               range >>= 1;
2604*f6dc9357SAndroid Build Coastguard Worker               p->rc.low += range & (0 - (pos2 >> 31));
2605*f6dc9357SAndroid Build Coastguard Worker               pos2 += pos2;
2606*f6dc9357SAndroid Build Coastguard Worker               RC_NORM(&p->rc)
2607*f6dc9357SAndroid Build Coastguard Worker             }
2608*f6dc9357SAndroid Build Coastguard Worker             while (pos2 != 0xF0000000);
2609*f6dc9357SAndroid Build Coastguard Worker 
2610*f6dc9357SAndroid Build Coastguard Worker 
2611*f6dc9357SAndroid Build Coastguard Worker             // RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);
2612*f6dc9357SAndroid Build Coastguard Worker 
2613*f6dc9357SAndroid Build Coastguard Worker             {
2614*f6dc9357SAndroid Build Coastguard Worker               unsigned m = 1;
2615*f6dc9357SAndroid Build Coastguard Worker               unsigned bit;
2616*f6dc9357SAndroid Build Coastguard Worker               bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit)  m = (m << 1) + bit;
2617*f6dc9357SAndroid Build Coastguard Worker               bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit)  m = (m << 1) + bit;
2618*f6dc9357SAndroid Build Coastguard Worker               bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit)  m = (m << 1) + bit;
2619*f6dc9357SAndroid Build Coastguard Worker               bit = dist & 1;             RC_BIT(&p->rc, p->posAlignEncoder + m, bit)
2620*f6dc9357SAndroid Build Coastguard Worker               p->rc.range = range;
2621*f6dc9357SAndroid Build Coastguard Worker               // p->alignPriceCount++;
2622*f6dc9357SAndroid Build Coastguard Worker             }
2623*f6dc9357SAndroid Build Coastguard Worker           }
2624*f6dc9357SAndroid Build Coastguard Worker         }
2625*f6dc9357SAndroid Build Coastguard Worker       }
2626*f6dc9357SAndroid Build Coastguard Worker     }
2627*f6dc9357SAndroid Build Coastguard Worker 
2628*f6dc9357SAndroid Build Coastguard Worker     nowPos32 += (UInt32)len;
2629*f6dc9357SAndroid Build Coastguard Worker     p->additionalOffset -= len;
2630*f6dc9357SAndroid Build Coastguard Worker 
2631*f6dc9357SAndroid Build Coastguard Worker     if (p->additionalOffset == 0)
2632*f6dc9357SAndroid Build Coastguard Worker     {
2633*f6dc9357SAndroid Build Coastguard Worker       UInt32 processed;
2634*f6dc9357SAndroid Build Coastguard Worker 
2635*f6dc9357SAndroid Build Coastguard Worker       if (!p->fastMode)
2636*f6dc9357SAndroid Build Coastguard Worker       {
2637*f6dc9357SAndroid Build Coastguard Worker         /*
2638*f6dc9357SAndroid Build Coastguard Worker         if (p->alignPriceCount >= 16) // kAlignTableSize
2639*f6dc9357SAndroid Build Coastguard Worker           FillAlignPrices(p);
2640*f6dc9357SAndroid Build Coastguard Worker         if (p->matchPriceCount >= 128)
2641*f6dc9357SAndroid Build Coastguard Worker           FillDistancesPrices(p);
2642*f6dc9357SAndroid Build Coastguard Worker         if (p->lenEnc.counter <= 0)
2643*f6dc9357SAndroid Build Coastguard Worker           LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, &p->lenProbs, p->ProbPrices);
2644*f6dc9357SAndroid Build Coastguard Worker         */
2645*f6dc9357SAndroid Build Coastguard Worker         if (p->matchPriceCount >= 64)
2646*f6dc9357SAndroid Build Coastguard Worker         {
2647*f6dc9357SAndroid Build Coastguard Worker           FillAlignPrices(p);
2648*f6dc9357SAndroid Build Coastguard Worker           // { int y; for (y = 0; y < 100; y++) {
2649*f6dc9357SAndroid Build Coastguard Worker           FillDistancesPrices(p);
2650*f6dc9357SAndroid Build Coastguard Worker           // }}
2651*f6dc9357SAndroid Build Coastguard Worker           LenPriceEnc_UpdateTables(&p->lenEnc, (unsigned)1 << p->pb, &p->lenProbs, p->ProbPrices);
2652*f6dc9357SAndroid Build Coastguard Worker         }
2653*f6dc9357SAndroid Build Coastguard Worker         if (p->repLenEncCounter <= 0)
2654*f6dc9357SAndroid Build Coastguard Worker         {
2655*f6dc9357SAndroid Build Coastguard Worker           p->repLenEncCounter = REP_LEN_COUNT;
2656*f6dc9357SAndroid Build Coastguard Worker           LenPriceEnc_UpdateTables(&p->repLenEnc, (unsigned)1 << p->pb, &p->repLenProbs, p->ProbPrices);
2657*f6dc9357SAndroid Build Coastguard Worker         }
2658*f6dc9357SAndroid Build Coastguard Worker       }
2659*f6dc9357SAndroid Build Coastguard Worker 
2660*f6dc9357SAndroid Build Coastguard Worker       if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
2661*f6dc9357SAndroid Build Coastguard Worker         break;
2662*f6dc9357SAndroid Build Coastguard Worker       processed = nowPos32 - startPos32;
2663*f6dc9357SAndroid Build Coastguard Worker 
2664*f6dc9357SAndroid Build Coastguard Worker       if (maxPackSize)
2665*f6dc9357SAndroid Build Coastguard Worker       {
2666*f6dc9357SAndroid Build Coastguard Worker         if (processed + kNumOpts + 300 >= maxUnpackSize
2667*f6dc9357SAndroid Build Coastguard Worker             || RangeEnc_GetProcessed_sizet(&p->rc) + kPackReserve >= maxPackSize)
2668*f6dc9357SAndroid Build Coastguard Worker           break;
2669*f6dc9357SAndroid Build Coastguard Worker       }
2670*f6dc9357SAndroid Build Coastguard Worker       else if (processed >= (1 << 17))
2671*f6dc9357SAndroid Build Coastguard Worker       {
2672*f6dc9357SAndroid Build Coastguard Worker         p->nowPos64 += nowPos32 - startPos32;
2673*f6dc9357SAndroid Build Coastguard Worker         return CheckErrors(p);
2674*f6dc9357SAndroid Build Coastguard Worker       }
2675*f6dc9357SAndroid Build Coastguard Worker     }
2676*f6dc9357SAndroid Build Coastguard Worker   }
2677*f6dc9357SAndroid Build Coastguard Worker 
2678*f6dc9357SAndroid Build Coastguard Worker   p->nowPos64 += nowPos32 - startPos32;
2679*f6dc9357SAndroid Build Coastguard Worker   return Flush(p, nowPos32);
2680*f6dc9357SAndroid Build Coastguard Worker }
2681*f6dc9357SAndroid Build Coastguard Worker 
2682*f6dc9357SAndroid Build Coastguard Worker 
2683*f6dc9357SAndroid Build Coastguard Worker 
2684*f6dc9357SAndroid Build Coastguard Worker #define kBigHashDicLimit ((UInt32)1 << 24)
2685*f6dc9357SAndroid Build Coastguard Worker 
LzmaEnc_Alloc(CLzmaEnc * p,UInt32 keepWindowSize,ISzAllocPtr alloc,ISzAllocPtr allocBig)2686*f6dc9357SAndroid Build Coastguard Worker static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
2687*f6dc9357SAndroid Build Coastguard Worker {
2688*f6dc9357SAndroid Build Coastguard Worker   UInt32 beforeSize = kNumOpts;
2689*f6dc9357SAndroid Build Coastguard Worker   UInt32 dictSize;
2690*f6dc9357SAndroid Build Coastguard Worker 
2691*f6dc9357SAndroid Build Coastguard Worker   if (!RangeEnc_Alloc(&p->rc, alloc))
2692*f6dc9357SAndroid Build Coastguard Worker     return SZ_ERROR_MEM;
2693*f6dc9357SAndroid Build Coastguard Worker 
2694*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
2695*f6dc9357SAndroid Build Coastguard Worker   p->mtMode = (p->multiThread && !p->fastMode && (MFB.btMode != 0));
2696*f6dc9357SAndroid Build Coastguard Worker   #endif
2697*f6dc9357SAndroid Build Coastguard Worker 
2698*f6dc9357SAndroid Build Coastguard Worker   {
2699*f6dc9357SAndroid Build Coastguard Worker     const unsigned lclp = p->lc + p->lp;
2700*f6dc9357SAndroid Build Coastguard Worker     if (!p->litProbs || !p->saveState.litProbs || p->lclp != lclp)
2701*f6dc9357SAndroid Build Coastguard Worker     {
2702*f6dc9357SAndroid Build Coastguard Worker       LzmaEnc_FreeLits(p, alloc);
2703*f6dc9357SAndroid Build Coastguard Worker       p->litProbs =           (CLzmaProb *)ISzAlloc_Alloc(alloc, ((size_t)0x300 * sizeof(CLzmaProb)) << lclp);
2704*f6dc9357SAndroid Build Coastguard Worker       p->saveState.litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((size_t)0x300 * sizeof(CLzmaProb)) << lclp);
2705*f6dc9357SAndroid Build Coastguard Worker       if (!p->litProbs || !p->saveState.litProbs)
2706*f6dc9357SAndroid Build Coastguard Worker       {
2707*f6dc9357SAndroid Build Coastguard Worker         LzmaEnc_FreeLits(p, alloc);
2708*f6dc9357SAndroid Build Coastguard Worker         return SZ_ERROR_MEM;
2709*f6dc9357SAndroid Build Coastguard Worker       }
2710*f6dc9357SAndroid Build Coastguard Worker       p->lclp = lclp;
2711*f6dc9357SAndroid Build Coastguard Worker     }
2712*f6dc9357SAndroid Build Coastguard Worker   }
2713*f6dc9357SAndroid Build Coastguard Worker 
2714*f6dc9357SAndroid Build Coastguard Worker   MFB.bigHash = (Byte)(p->dictSize > kBigHashDicLimit ? 1 : 0);
2715*f6dc9357SAndroid Build Coastguard Worker 
2716*f6dc9357SAndroid Build Coastguard Worker 
2717*f6dc9357SAndroid Build Coastguard Worker   dictSize = p->dictSize;
2718*f6dc9357SAndroid Build Coastguard Worker   if (dictSize == ((UInt32)2 << 30) ||
2719*f6dc9357SAndroid Build Coastguard Worker       dictSize == ((UInt32)3 << 30))
2720*f6dc9357SAndroid Build Coastguard Worker   {
2721*f6dc9357SAndroid Build Coastguard Worker     /* 21.03 : here we reduce the dictionary for 2 reasons:
2722*f6dc9357SAndroid Build Coastguard Worker        1) we don't want 32-bit back_distance matches in decoder for 2 GB dictionary.
2723*f6dc9357SAndroid Build Coastguard Worker        2) we want to elimate useless last MatchFinder_Normalize3() for corner cases,
2724*f6dc9357SAndroid Build Coastguard Worker           where data size is aligned for 1 GB: 5/6/8 GB.
2725*f6dc9357SAndroid Build Coastguard Worker           That reducing must be >= 1 for such corner cases. */
2726*f6dc9357SAndroid Build Coastguard Worker     dictSize -= 1;
2727*f6dc9357SAndroid Build Coastguard Worker   }
2728*f6dc9357SAndroid Build Coastguard Worker 
2729*f6dc9357SAndroid Build Coastguard Worker   if (beforeSize + dictSize < keepWindowSize)
2730*f6dc9357SAndroid Build Coastguard Worker     beforeSize = keepWindowSize - dictSize;
2731*f6dc9357SAndroid Build Coastguard Worker 
2732*f6dc9357SAndroid Build Coastguard Worker   /* in worst case we can look ahead for
2733*f6dc9357SAndroid Build Coastguard Worker         max(LZMA_MATCH_LEN_MAX, numFastBytes + 1 + numFastBytes) bytes.
2734*f6dc9357SAndroid Build Coastguard Worker      we send larger value for (keepAfter) to MantchFinder_Create():
2735*f6dc9357SAndroid Build Coastguard Worker         (numFastBytes + LZMA_MATCH_LEN_MAX + 1)
2736*f6dc9357SAndroid Build Coastguard Worker   */
2737*f6dc9357SAndroid Build Coastguard Worker 
2738*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
2739*f6dc9357SAndroid Build Coastguard Worker   if (p->mtMode)
2740*f6dc9357SAndroid Build Coastguard Worker   {
2741*f6dc9357SAndroid Build Coastguard Worker     RINOK(MatchFinderMt_Create(&p->matchFinderMt, dictSize, beforeSize,
2742*f6dc9357SAndroid Build Coastguard Worker         p->numFastBytes, LZMA_MATCH_LEN_MAX + 1 /* 18.04 */
2743*f6dc9357SAndroid Build Coastguard Worker         , allocBig))
2744*f6dc9357SAndroid Build Coastguard Worker     p->matchFinderObj = &p->matchFinderMt;
2745*f6dc9357SAndroid Build Coastguard Worker     MFB.bigHash = (Byte)(MFB.hashMask >= 0xFFFFFF ? 1 : 0);
2746*f6dc9357SAndroid Build Coastguard Worker     MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
2747*f6dc9357SAndroid Build Coastguard Worker   }
2748*f6dc9357SAndroid Build Coastguard Worker   else
2749*f6dc9357SAndroid Build Coastguard Worker   #endif
2750*f6dc9357SAndroid Build Coastguard Worker   {
2751*f6dc9357SAndroid Build Coastguard Worker     if (!MatchFinder_Create(&MFB, dictSize, beforeSize,
2752*f6dc9357SAndroid Build Coastguard Worker         p->numFastBytes, LZMA_MATCH_LEN_MAX + 1 /* 21.03 */
2753*f6dc9357SAndroid Build Coastguard Worker         , allocBig))
2754*f6dc9357SAndroid Build Coastguard Worker       return SZ_ERROR_MEM;
2755*f6dc9357SAndroid Build Coastguard Worker     p->matchFinderObj = &MFB;
2756*f6dc9357SAndroid Build Coastguard Worker     MatchFinder_CreateVTable(&MFB, &p->matchFinder);
2757*f6dc9357SAndroid Build Coastguard Worker   }
2758*f6dc9357SAndroid Build Coastguard Worker 
2759*f6dc9357SAndroid Build Coastguard Worker   return SZ_OK;
2760*f6dc9357SAndroid Build Coastguard Worker }
2761*f6dc9357SAndroid Build Coastguard Worker 
LzmaEnc_Init(CLzmaEnc * p)2762*f6dc9357SAndroid Build Coastguard Worker static void LzmaEnc_Init(CLzmaEnc *p)
2763*f6dc9357SAndroid Build Coastguard Worker {
2764*f6dc9357SAndroid Build Coastguard Worker   unsigned i;
2765*f6dc9357SAndroid Build Coastguard Worker   p->state = 0;
2766*f6dc9357SAndroid Build Coastguard Worker   p->reps[0] =
2767*f6dc9357SAndroid Build Coastguard Worker   p->reps[1] =
2768*f6dc9357SAndroid Build Coastguard Worker   p->reps[2] =
2769*f6dc9357SAndroid Build Coastguard Worker   p->reps[3] = 1;
2770*f6dc9357SAndroid Build Coastguard Worker 
2771*f6dc9357SAndroid Build Coastguard Worker   RangeEnc_Init(&p->rc);
2772*f6dc9357SAndroid Build Coastguard Worker 
2773*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < (1 << kNumAlignBits); i++)
2774*f6dc9357SAndroid Build Coastguard Worker     p->posAlignEncoder[i] = kProbInitValue;
2775*f6dc9357SAndroid Build Coastguard Worker 
2776*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < kNumStates; i++)
2777*f6dc9357SAndroid Build Coastguard Worker   {
2778*f6dc9357SAndroid Build Coastguard Worker     unsigned j;
2779*f6dc9357SAndroid Build Coastguard Worker     for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++)
2780*f6dc9357SAndroid Build Coastguard Worker     {
2781*f6dc9357SAndroid Build Coastguard Worker       p->isMatch[i][j] = kProbInitValue;
2782*f6dc9357SAndroid Build Coastguard Worker       p->isRep0Long[i][j] = kProbInitValue;
2783*f6dc9357SAndroid Build Coastguard Worker     }
2784*f6dc9357SAndroid Build Coastguard Worker     p->isRep[i] = kProbInitValue;
2785*f6dc9357SAndroid Build Coastguard Worker     p->isRepG0[i] = kProbInitValue;
2786*f6dc9357SAndroid Build Coastguard Worker     p->isRepG1[i] = kProbInitValue;
2787*f6dc9357SAndroid Build Coastguard Worker     p->isRepG2[i] = kProbInitValue;
2788*f6dc9357SAndroid Build Coastguard Worker   }
2789*f6dc9357SAndroid Build Coastguard Worker 
2790*f6dc9357SAndroid Build Coastguard Worker   {
2791*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < kNumLenToPosStates; i++)
2792*f6dc9357SAndroid Build Coastguard Worker     {
2793*f6dc9357SAndroid Build Coastguard Worker       CLzmaProb *probs = p->posSlotEncoder[i];
2794*f6dc9357SAndroid Build Coastguard Worker       unsigned j;
2795*f6dc9357SAndroid Build Coastguard Worker       for (j = 0; j < (1 << kNumPosSlotBits); j++)
2796*f6dc9357SAndroid Build Coastguard Worker         probs[j] = kProbInitValue;
2797*f6dc9357SAndroid Build Coastguard Worker     }
2798*f6dc9357SAndroid Build Coastguard Worker   }
2799*f6dc9357SAndroid Build Coastguard Worker   {
2800*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < kNumFullDistances; i++)
2801*f6dc9357SAndroid Build Coastguard Worker       p->posEncoders[i] = kProbInitValue;
2802*f6dc9357SAndroid Build Coastguard Worker   }
2803*f6dc9357SAndroid Build Coastguard Worker 
2804*f6dc9357SAndroid Build Coastguard Worker   {
2805*f6dc9357SAndroid Build Coastguard Worker     const size_t num = (size_t)0x300 << (p->lp + p->lc);
2806*f6dc9357SAndroid Build Coastguard Worker     size_t k;
2807*f6dc9357SAndroid Build Coastguard Worker     CLzmaProb *probs = p->litProbs;
2808*f6dc9357SAndroid Build Coastguard Worker     for (k = 0; k < num; k++)
2809*f6dc9357SAndroid Build Coastguard Worker       probs[k] = kProbInitValue;
2810*f6dc9357SAndroid Build Coastguard Worker   }
2811*f6dc9357SAndroid Build Coastguard Worker 
2812*f6dc9357SAndroid Build Coastguard Worker 
2813*f6dc9357SAndroid Build Coastguard Worker   LenEnc_Init(&p->lenProbs);
2814*f6dc9357SAndroid Build Coastguard Worker   LenEnc_Init(&p->repLenProbs);
2815*f6dc9357SAndroid Build Coastguard Worker 
2816*f6dc9357SAndroid Build Coastguard Worker   p->optEnd = 0;
2817*f6dc9357SAndroid Build Coastguard Worker   p->optCur = 0;
2818*f6dc9357SAndroid Build Coastguard Worker 
2819*f6dc9357SAndroid Build Coastguard Worker   {
2820*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < kNumOpts; i++)
2821*f6dc9357SAndroid Build Coastguard Worker       p->opt[i].price = kInfinityPrice;
2822*f6dc9357SAndroid Build Coastguard Worker   }
2823*f6dc9357SAndroid Build Coastguard Worker 
2824*f6dc9357SAndroid Build Coastguard Worker   p->additionalOffset = 0;
2825*f6dc9357SAndroid Build Coastguard Worker 
2826*f6dc9357SAndroid Build Coastguard Worker   p->pbMask = ((unsigned)1 << p->pb) - 1;
2827*f6dc9357SAndroid Build Coastguard Worker   p->lpMask = ((UInt32)0x100 << p->lp) - ((unsigned)0x100 >> p->lc);
2828*f6dc9357SAndroid Build Coastguard Worker 
2829*f6dc9357SAndroid Build Coastguard Worker   // p->mf_Failure = False;
2830*f6dc9357SAndroid Build Coastguard Worker }
2831*f6dc9357SAndroid Build Coastguard Worker 
2832*f6dc9357SAndroid Build Coastguard Worker 
LzmaEnc_InitPrices(CLzmaEnc * p)2833*f6dc9357SAndroid Build Coastguard Worker static void LzmaEnc_InitPrices(CLzmaEnc *p)
2834*f6dc9357SAndroid Build Coastguard Worker {
2835*f6dc9357SAndroid Build Coastguard Worker   if (!p->fastMode)
2836*f6dc9357SAndroid Build Coastguard Worker   {
2837*f6dc9357SAndroid Build Coastguard Worker     FillDistancesPrices(p);
2838*f6dc9357SAndroid Build Coastguard Worker     FillAlignPrices(p);
2839*f6dc9357SAndroid Build Coastguard Worker   }
2840*f6dc9357SAndroid Build Coastguard Worker 
2841*f6dc9357SAndroid Build Coastguard Worker   p->lenEnc.tableSize =
2842*f6dc9357SAndroid Build Coastguard Worker   p->repLenEnc.tableSize =
2843*f6dc9357SAndroid Build Coastguard Worker       p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN;
2844*f6dc9357SAndroid Build Coastguard Worker 
2845*f6dc9357SAndroid Build Coastguard Worker   p->repLenEncCounter = REP_LEN_COUNT;
2846*f6dc9357SAndroid Build Coastguard Worker 
2847*f6dc9357SAndroid Build Coastguard Worker   LenPriceEnc_UpdateTables(&p->lenEnc, (unsigned)1 << p->pb, &p->lenProbs, p->ProbPrices);
2848*f6dc9357SAndroid Build Coastguard Worker   LenPriceEnc_UpdateTables(&p->repLenEnc, (unsigned)1 << p->pb, &p->repLenProbs, p->ProbPrices);
2849*f6dc9357SAndroid Build Coastguard Worker }
2850*f6dc9357SAndroid Build Coastguard Worker 
LzmaEnc_AllocAndInit(CLzmaEnc * p,UInt32 keepWindowSize,ISzAllocPtr alloc,ISzAllocPtr allocBig)2851*f6dc9357SAndroid Build Coastguard Worker static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
2852*f6dc9357SAndroid Build Coastguard Worker {
2853*f6dc9357SAndroid Build Coastguard Worker   unsigned i;
2854*f6dc9357SAndroid Build Coastguard Worker   for (i = kEndPosModelIndex / 2; i < kDicLogSizeMax; i++)
2855*f6dc9357SAndroid Build Coastguard Worker     if (p->dictSize <= ((UInt32)1 << i))
2856*f6dc9357SAndroid Build Coastguard Worker       break;
2857*f6dc9357SAndroid Build Coastguard Worker   p->distTableSize = i * 2;
2858*f6dc9357SAndroid Build Coastguard Worker 
2859*f6dc9357SAndroid Build Coastguard Worker   p->finished = False;
2860*f6dc9357SAndroid Build Coastguard Worker   p->result = SZ_OK;
2861*f6dc9357SAndroid Build Coastguard Worker   p->nowPos64 = 0;
2862*f6dc9357SAndroid Build Coastguard Worker   p->needInit = 1;
2863*f6dc9357SAndroid Build Coastguard Worker   RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig))
2864*f6dc9357SAndroid Build Coastguard Worker   LzmaEnc_Init(p);
2865*f6dc9357SAndroid Build Coastguard Worker   LzmaEnc_InitPrices(p);
2866*f6dc9357SAndroid Build Coastguard Worker   return SZ_OK;
2867*f6dc9357SAndroid Build Coastguard Worker }
2868*f6dc9357SAndroid Build Coastguard Worker 
LzmaEnc_Prepare(CLzmaEncHandle p,ISeqOutStreamPtr outStream,ISeqInStreamPtr inStream,ISzAllocPtr alloc,ISzAllocPtr allocBig)2869*f6dc9357SAndroid Build Coastguard Worker static SRes LzmaEnc_Prepare(CLzmaEncHandle p,
2870*f6dc9357SAndroid Build Coastguard Worker     ISeqOutStreamPtr outStream,
2871*f6dc9357SAndroid Build Coastguard Worker     ISeqInStreamPtr inStream,
2872*f6dc9357SAndroid Build Coastguard Worker     ISzAllocPtr alloc, ISzAllocPtr allocBig)
2873*f6dc9357SAndroid Build Coastguard Worker {
2874*f6dc9357SAndroid Build Coastguard Worker   // GET_CLzmaEnc_p
2875*f6dc9357SAndroid Build Coastguard Worker   MatchFinder_SET_STREAM(&MFB, inStream)
2876*f6dc9357SAndroid Build Coastguard Worker   p->rc.outStream = outStream;
2877*f6dc9357SAndroid Build Coastguard Worker   return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig);
2878*f6dc9357SAndroid Build Coastguard Worker }
2879*f6dc9357SAndroid Build Coastguard Worker 
LzmaEnc_PrepareForLzma2(CLzmaEncHandle p,ISeqInStreamPtr inStream,UInt32 keepWindowSize,ISzAllocPtr alloc,ISzAllocPtr allocBig)2880*f6dc9357SAndroid Build Coastguard Worker SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle p,
2881*f6dc9357SAndroid Build Coastguard Worker     ISeqInStreamPtr inStream, UInt32 keepWindowSize,
2882*f6dc9357SAndroid Build Coastguard Worker     ISzAllocPtr alloc, ISzAllocPtr allocBig)
2883*f6dc9357SAndroid Build Coastguard Worker {
2884*f6dc9357SAndroid Build Coastguard Worker   // GET_CLzmaEnc_p
2885*f6dc9357SAndroid Build Coastguard Worker   MatchFinder_SET_STREAM(&MFB, inStream)
2886*f6dc9357SAndroid Build Coastguard Worker   return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
2887*f6dc9357SAndroid Build Coastguard Worker }
2888*f6dc9357SAndroid Build Coastguard Worker 
LzmaEnc_MemPrepare(CLzmaEncHandle p,const Byte * src,SizeT srcLen,UInt32 keepWindowSize,ISzAllocPtr alloc,ISzAllocPtr allocBig)2889*f6dc9357SAndroid Build Coastguard Worker SRes LzmaEnc_MemPrepare(CLzmaEncHandle p,
2890*f6dc9357SAndroid Build Coastguard Worker     const Byte *src, SizeT srcLen,
2891*f6dc9357SAndroid Build Coastguard Worker     UInt32 keepWindowSize,
2892*f6dc9357SAndroid Build Coastguard Worker     ISzAllocPtr alloc, ISzAllocPtr allocBig)
2893*f6dc9357SAndroid Build Coastguard Worker {
2894*f6dc9357SAndroid Build Coastguard Worker   // GET_CLzmaEnc_p
2895*f6dc9357SAndroid Build Coastguard Worker   MatchFinder_SET_DIRECT_INPUT_BUF(&MFB, src, srcLen)
2896*f6dc9357SAndroid Build Coastguard Worker   LzmaEnc_SetDataSize(p, srcLen);
2897*f6dc9357SAndroid Build Coastguard Worker   return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
2898*f6dc9357SAndroid Build Coastguard Worker }
2899*f6dc9357SAndroid Build Coastguard Worker 
LzmaEnc_Finish(CLzmaEncHandle p)2900*f6dc9357SAndroid Build Coastguard Worker void LzmaEnc_Finish(CLzmaEncHandle p)
2901*f6dc9357SAndroid Build Coastguard Worker {
2902*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
2903*f6dc9357SAndroid Build Coastguard Worker   // GET_CLzmaEnc_p
2904*f6dc9357SAndroid Build Coastguard Worker   if (p->mtMode)
2905*f6dc9357SAndroid Build Coastguard Worker     MatchFinderMt_ReleaseStream(&p->matchFinderMt);
2906*f6dc9357SAndroid Build Coastguard Worker   #else
2907*f6dc9357SAndroid Build Coastguard Worker   UNUSED_VAR(p)
2908*f6dc9357SAndroid Build Coastguard Worker   #endif
2909*f6dc9357SAndroid Build Coastguard Worker }
2910*f6dc9357SAndroid Build Coastguard Worker 
2911*f6dc9357SAndroid Build Coastguard Worker 
2912*f6dc9357SAndroid Build Coastguard Worker typedef struct
2913*f6dc9357SAndroid Build Coastguard Worker {
2914*f6dc9357SAndroid Build Coastguard Worker   ISeqOutStream vt;
2915*f6dc9357SAndroid Build Coastguard Worker   Byte *data;
2916*f6dc9357SAndroid Build Coastguard Worker   size_t rem;
2917*f6dc9357SAndroid Build Coastguard Worker   BoolInt overflow;
2918*f6dc9357SAndroid Build Coastguard Worker } CLzmaEnc_SeqOutStreamBuf;
2919*f6dc9357SAndroid Build Coastguard Worker 
SeqOutStreamBuf_Write(ISeqOutStreamPtr pp,const void * data,size_t size)2920*f6dc9357SAndroid Build Coastguard Worker static size_t SeqOutStreamBuf_Write(ISeqOutStreamPtr pp, const void *data, size_t size)
2921*f6dc9357SAndroid Build Coastguard Worker {
2922*f6dc9357SAndroid Build Coastguard Worker   Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CLzmaEnc_SeqOutStreamBuf)
2923*f6dc9357SAndroid Build Coastguard Worker   if (p->rem < size)
2924*f6dc9357SAndroid Build Coastguard Worker   {
2925*f6dc9357SAndroid Build Coastguard Worker     size = p->rem;
2926*f6dc9357SAndroid Build Coastguard Worker     p->overflow = True;
2927*f6dc9357SAndroid Build Coastguard Worker   }
2928*f6dc9357SAndroid Build Coastguard Worker   if (size != 0)
2929*f6dc9357SAndroid Build Coastguard Worker   {
2930*f6dc9357SAndroid Build Coastguard Worker     memcpy(p->data, data, size);
2931*f6dc9357SAndroid Build Coastguard Worker     p->rem -= size;
2932*f6dc9357SAndroid Build Coastguard Worker     p->data += size;
2933*f6dc9357SAndroid Build Coastguard Worker   }
2934*f6dc9357SAndroid Build Coastguard Worker   return size;
2935*f6dc9357SAndroid Build Coastguard Worker }
2936*f6dc9357SAndroid Build Coastguard Worker 
2937*f6dc9357SAndroid Build Coastguard Worker 
2938*f6dc9357SAndroid Build Coastguard Worker /*
2939*f6dc9357SAndroid Build Coastguard Worker UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle p)
2940*f6dc9357SAndroid Build Coastguard Worker {
2941*f6dc9357SAndroid Build Coastguard Worker   GET_const_CLzmaEnc_p
2942*f6dc9357SAndroid Build Coastguard Worker   return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
2943*f6dc9357SAndroid Build Coastguard Worker }
2944*f6dc9357SAndroid Build Coastguard Worker */
2945*f6dc9357SAndroid Build Coastguard Worker 
LzmaEnc_GetCurBuf(CLzmaEncHandle p)2946*f6dc9357SAndroid Build Coastguard Worker const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle p)
2947*f6dc9357SAndroid Build Coastguard Worker {
2948*f6dc9357SAndroid Build Coastguard Worker   // GET_const_CLzmaEnc_p
2949*f6dc9357SAndroid Build Coastguard Worker   return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
2950*f6dc9357SAndroid Build Coastguard Worker }
2951*f6dc9357SAndroid Build Coastguard Worker 
2952*f6dc9357SAndroid Build Coastguard Worker 
2953*f6dc9357SAndroid Build Coastguard Worker // (desiredPackSize == 0) is not allowed
LzmaEnc_CodeOneMemBlock(CLzmaEncHandle p,BoolInt reInit,Byte * dest,size_t * destLen,UInt32 desiredPackSize,UInt32 * unpackSize)2954*f6dc9357SAndroid Build Coastguard Worker SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle p, BoolInt reInit,
2955*f6dc9357SAndroid Build Coastguard Worker     Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
2956*f6dc9357SAndroid Build Coastguard Worker {
2957*f6dc9357SAndroid Build Coastguard Worker   // GET_CLzmaEnc_p
2958*f6dc9357SAndroid Build Coastguard Worker   UInt64 nowPos64;
2959*f6dc9357SAndroid Build Coastguard Worker   SRes res;
2960*f6dc9357SAndroid Build Coastguard Worker   CLzmaEnc_SeqOutStreamBuf outStream;
2961*f6dc9357SAndroid Build Coastguard Worker 
2962*f6dc9357SAndroid Build Coastguard Worker   outStream.vt.Write = SeqOutStreamBuf_Write;
2963*f6dc9357SAndroid Build Coastguard Worker   outStream.data = dest;
2964*f6dc9357SAndroid Build Coastguard Worker   outStream.rem = *destLen;
2965*f6dc9357SAndroid Build Coastguard Worker   outStream.overflow = False;
2966*f6dc9357SAndroid Build Coastguard Worker 
2967*f6dc9357SAndroid Build Coastguard Worker   p->writeEndMark = False;
2968*f6dc9357SAndroid Build Coastguard Worker   p->finished = False;
2969*f6dc9357SAndroid Build Coastguard Worker   p->result = SZ_OK;
2970*f6dc9357SAndroid Build Coastguard Worker 
2971*f6dc9357SAndroid Build Coastguard Worker   if (reInit)
2972*f6dc9357SAndroid Build Coastguard Worker     LzmaEnc_Init(p);
2973*f6dc9357SAndroid Build Coastguard Worker   LzmaEnc_InitPrices(p);
2974*f6dc9357SAndroid Build Coastguard Worker   RangeEnc_Init(&p->rc);
2975*f6dc9357SAndroid Build Coastguard Worker   p->rc.outStream = &outStream.vt;
2976*f6dc9357SAndroid Build Coastguard Worker   nowPos64 = p->nowPos64;
2977*f6dc9357SAndroid Build Coastguard Worker 
2978*f6dc9357SAndroid Build Coastguard Worker   res = LzmaEnc_CodeOneBlock(p, desiredPackSize, *unpackSize);
2979*f6dc9357SAndroid Build Coastguard Worker 
2980*f6dc9357SAndroid Build Coastguard Worker   *unpackSize = (UInt32)(p->nowPos64 - nowPos64);
2981*f6dc9357SAndroid Build Coastguard Worker   *destLen -= outStream.rem;
2982*f6dc9357SAndroid Build Coastguard Worker   if (outStream.overflow)
2983*f6dc9357SAndroid Build Coastguard Worker     return SZ_ERROR_OUTPUT_EOF;
2984*f6dc9357SAndroid Build Coastguard Worker 
2985*f6dc9357SAndroid Build Coastguard Worker   return res;
2986*f6dc9357SAndroid Build Coastguard Worker }
2987*f6dc9357SAndroid Build Coastguard Worker 
2988*f6dc9357SAndroid Build Coastguard Worker 
2989*f6dc9357SAndroid Build Coastguard Worker Z7_NO_INLINE
LzmaEnc_Encode2(CLzmaEnc * p,ICompressProgressPtr progress)2990*f6dc9357SAndroid Build Coastguard Worker static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgressPtr progress)
2991*f6dc9357SAndroid Build Coastguard Worker {
2992*f6dc9357SAndroid Build Coastguard Worker   SRes res = SZ_OK;
2993*f6dc9357SAndroid Build Coastguard Worker 
2994*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
2995*f6dc9357SAndroid Build Coastguard Worker   Byte allocaDummy[0x300];
2996*f6dc9357SAndroid Build Coastguard Worker   allocaDummy[0] = 0;
2997*f6dc9357SAndroid Build Coastguard Worker   allocaDummy[1] = allocaDummy[0];
2998*f6dc9357SAndroid Build Coastguard Worker   #endif
2999*f6dc9357SAndroid Build Coastguard Worker 
3000*f6dc9357SAndroid Build Coastguard Worker   for (;;)
3001*f6dc9357SAndroid Build Coastguard Worker   {
3002*f6dc9357SAndroid Build Coastguard Worker     res = LzmaEnc_CodeOneBlock(p, 0, 0);
3003*f6dc9357SAndroid Build Coastguard Worker     if (res != SZ_OK || p->finished)
3004*f6dc9357SAndroid Build Coastguard Worker       break;
3005*f6dc9357SAndroid Build Coastguard Worker     if (progress)
3006*f6dc9357SAndroid Build Coastguard Worker     {
3007*f6dc9357SAndroid Build Coastguard Worker       res = ICompressProgress_Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
3008*f6dc9357SAndroid Build Coastguard Worker       if (res != SZ_OK)
3009*f6dc9357SAndroid Build Coastguard Worker       {
3010*f6dc9357SAndroid Build Coastguard Worker         res = SZ_ERROR_PROGRESS;
3011*f6dc9357SAndroid Build Coastguard Worker         break;
3012*f6dc9357SAndroid Build Coastguard Worker       }
3013*f6dc9357SAndroid Build Coastguard Worker     }
3014*f6dc9357SAndroid Build Coastguard Worker   }
3015*f6dc9357SAndroid Build Coastguard Worker 
3016*f6dc9357SAndroid Build Coastguard Worker   LzmaEnc_Finish((CLzmaEncHandle)(void *)p);
3017*f6dc9357SAndroid Build Coastguard Worker 
3018*f6dc9357SAndroid Build Coastguard Worker   /*
3019*f6dc9357SAndroid Build Coastguard Worker   if (res == SZ_OK && !Inline_MatchFinder_IsFinishedOK(&MFB))
3020*f6dc9357SAndroid Build Coastguard Worker     res = SZ_ERROR_FAIL;
3021*f6dc9357SAndroid Build Coastguard Worker   }
3022*f6dc9357SAndroid Build Coastguard Worker   */
3023*f6dc9357SAndroid Build Coastguard Worker 
3024*f6dc9357SAndroid Build Coastguard Worker   return res;
3025*f6dc9357SAndroid Build Coastguard Worker }
3026*f6dc9357SAndroid Build Coastguard Worker 
3027*f6dc9357SAndroid Build Coastguard Worker 
LzmaEnc_Encode(CLzmaEncHandle p,ISeqOutStreamPtr outStream,ISeqInStreamPtr inStream,ICompressProgressPtr progress,ISzAllocPtr alloc,ISzAllocPtr allocBig)3028*f6dc9357SAndroid Build Coastguard Worker SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, ICompressProgressPtr progress,
3029*f6dc9357SAndroid Build Coastguard Worker     ISzAllocPtr alloc, ISzAllocPtr allocBig)
3030*f6dc9357SAndroid Build Coastguard Worker {
3031*f6dc9357SAndroid Build Coastguard Worker   // GET_CLzmaEnc_p
3032*f6dc9357SAndroid Build Coastguard Worker   RINOK(LzmaEnc_Prepare(p, outStream, inStream, alloc, allocBig))
3033*f6dc9357SAndroid Build Coastguard Worker   return LzmaEnc_Encode2(p, progress);
3034*f6dc9357SAndroid Build Coastguard Worker }
3035*f6dc9357SAndroid Build Coastguard Worker 
3036*f6dc9357SAndroid Build Coastguard Worker 
LzmaEnc_WriteProperties(CLzmaEncHandle p,Byte * props,SizeT * size)3037*f6dc9357SAndroid Build Coastguard Worker SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *props, SizeT *size)
3038*f6dc9357SAndroid Build Coastguard Worker {
3039*f6dc9357SAndroid Build Coastguard Worker   if (*size < LZMA_PROPS_SIZE)
3040*f6dc9357SAndroid Build Coastguard Worker     return SZ_ERROR_PARAM;
3041*f6dc9357SAndroid Build Coastguard Worker   *size = LZMA_PROPS_SIZE;
3042*f6dc9357SAndroid Build Coastguard Worker   {
3043*f6dc9357SAndroid Build Coastguard Worker     // GET_CLzmaEnc_p
3044*f6dc9357SAndroid Build Coastguard Worker     const UInt32 dictSize = p->dictSize;
3045*f6dc9357SAndroid Build Coastguard Worker     UInt32 v;
3046*f6dc9357SAndroid Build Coastguard Worker     props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
3047*f6dc9357SAndroid Build Coastguard Worker 
3048*f6dc9357SAndroid Build Coastguard Worker     // we write aligned dictionary value to properties for lzma decoder
3049*f6dc9357SAndroid Build Coastguard Worker     if (dictSize >= ((UInt32)1 << 21))
3050*f6dc9357SAndroid Build Coastguard Worker     {
3051*f6dc9357SAndroid Build Coastguard Worker       const UInt32 kDictMask = ((UInt32)1 << 20) - 1;
3052*f6dc9357SAndroid Build Coastguard Worker       v = (dictSize + kDictMask) & ~kDictMask;
3053*f6dc9357SAndroid Build Coastguard Worker       if (v < dictSize)
3054*f6dc9357SAndroid Build Coastguard Worker         v = dictSize;
3055*f6dc9357SAndroid Build Coastguard Worker     }
3056*f6dc9357SAndroid Build Coastguard Worker     else
3057*f6dc9357SAndroid Build Coastguard Worker     {
3058*f6dc9357SAndroid Build Coastguard Worker       unsigned i = 11 * 2;
3059*f6dc9357SAndroid Build Coastguard Worker       do
3060*f6dc9357SAndroid Build Coastguard Worker       {
3061*f6dc9357SAndroid Build Coastguard Worker         v = (UInt32)(2 + (i & 1)) << (i >> 1);
3062*f6dc9357SAndroid Build Coastguard Worker         i++;
3063*f6dc9357SAndroid Build Coastguard Worker       }
3064*f6dc9357SAndroid Build Coastguard Worker       while (v < dictSize);
3065*f6dc9357SAndroid Build Coastguard Worker     }
3066*f6dc9357SAndroid Build Coastguard Worker 
3067*f6dc9357SAndroid Build Coastguard Worker     SetUi32(props + 1, v)
3068*f6dc9357SAndroid Build Coastguard Worker     return SZ_OK;
3069*f6dc9357SAndroid Build Coastguard Worker   }
3070*f6dc9357SAndroid Build Coastguard Worker }
3071*f6dc9357SAndroid Build Coastguard Worker 
3072*f6dc9357SAndroid Build Coastguard Worker 
LzmaEnc_IsWriteEndMark(CLzmaEncHandle p)3073*f6dc9357SAndroid Build Coastguard Worker unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p)
3074*f6dc9357SAndroid Build Coastguard Worker {
3075*f6dc9357SAndroid Build Coastguard Worker   // GET_CLzmaEnc_p
3076*f6dc9357SAndroid Build Coastguard Worker   return (unsigned)p->writeEndMark;
3077*f6dc9357SAndroid Build Coastguard Worker }
3078*f6dc9357SAndroid Build Coastguard Worker 
3079*f6dc9357SAndroid Build Coastguard Worker 
LzmaEnc_MemEncode(CLzmaEncHandle p,Byte * dest,SizeT * destLen,const Byte * src,SizeT srcLen,int writeEndMark,ICompressProgressPtr progress,ISzAllocPtr alloc,ISzAllocPtr allocBig)3080*f6dc9357SAndroid Build Coastguard Worker SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
3081*f6dc9357SAndroid Build Coastguard Worker     int writeEndMark, ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig)
3082*f6dc9357SAndroid Build Coastguard Worker {
3083*f6dc9357SAndroid Build Coastguard Worker   SRes res;
3084*f6dc9357SAndroid Build Coastguard Worker   // GET_CLzmaEnc_p
3085*f6dc9357SAndroid Build Coastguard Worker 
3086*f6dc9357SAndroid Build Coastguard Worker   CLzmaEnc_SeqOutStreamBuf outStream;
3087*f6dc9357SAndroid Build Coastguard Worker 
3088*f6dc9357SAndroid Build Coastguard Worker   outStream.vt.Write = SeqOutStreamBuf_Write;
3089*f6dc9357SAndroid Build Coastguard Worker   outStream.data = dest;
3090*f6dc9357SAndroid Build Coastguard Worker   outStream.rem = *destLen;
3091*f6dc9357SAndroid Build Coastguard Worker   outStream.overflow = False;
3092*f6dc9357SAndroid Build Coastguard Worker 
3093*f6dc9357SAndroid Build Coastguard Worker   p->writeEndMark = writeEndMark;
3094*f6dc9357SAndroid Build Coastguard Worker   p->rc.outStream = &outStream.vt;
3095*f6dc9357SAndroid Build Coastguard Worker 
3096*f6dc9357SAndroid Build Coastguard Worker   res = LzmaEnc_MemPrepare(p, src, srcLen, 0, alloc, allocBig);
3097*f6dc9357SAndroid Build Coastguard Worker 
3098*f6dc9357SAndroid Build Coastguard Worker   if (res == SZ_OK)
3099*f6dc9357SAndroid Build Coastguard Worker   {
3100*f6dc9357SAndroid Build Coastguard Worker     res = LzmaEnc_Encode2(p, progress);
3101*f6dc9357SAndroid Build Coastguard Worker     if (res == SZ_OK && p->nowPos64 != srcLen)
3102*f6dc9357SAndroid Build Coastguard Worker       res = SZ_ERROR_FAIL;
3103*f6dc9357SAndroid Build Coastguard Worker   }
3104*f6dc9357SAndroid Build Coastguard Worker 
3105*f6dc9357SAndroid Build Coastguard Worker   *destLen -= (SizeT)outStream.rem;
3106*f6dc9357SAndroid Build Coastguard Worker   if (outStream.overflow)
3107*f6dc9357SAndroid Build Coastguard Worker     return SZ_ERROR_OUTPUT_EOF;
3108*f6dc9357SAndroid Build Coastguard Worker   return res;
3109*f6dc9357SAndroid Build Coastguard Worker }
3110*f6dc9357SAndroid Build Coastguard Worker 
3111*f6dc9357SAndroid Build Coastguard Worker 
LzmaEncode(Byte * dest,SizeT * destLen,const Byte * src,SizeT srcLen,const CLzmaEncProps * props,Byte * propsEncoded,SizeT * propsSize,int writeEndMark,ICompressProgressPtr progress,ISzAllocPtr alloc,ISzAllocPtr allocBig)3112*f6dc9357SAndroid Build Coastguard Worker SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
3113*f6dc9357SAndroid Build Coastguard Worker     const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
3114*f6dc9357SAndroid Build Coastguard Worker     ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig)
3115*f6dc9357SAndroid Build Coastguard Worker {
3116*f6dc9357SAndroid Build Coastguard Worker   CLzmaEncHandle p = LzmaEnc_Create(alloc);
3117*f6dc9357SAndroid Build Coastguard Worker   SRes res;
3118*f6dc9357SAndroid Build Coastguard Worker   if (!p)
3119*f6dc9357SAndroid Build Coastguard Worker     return SZ_ERROR_MEM;
3120*f6dc9357SAndroid Build Coastguard Worker 
3121*f6dc9357SAndroid Build Coastguard Worker   res = LzmaEnc_SetProps(p, props);
3122*f6dc9357SAndroid Build Coastguard Worker   if (res == SZ_OK)
3123*f6dc9357SAndroid Build Coastguard Worker   {
3124*f6dc9357SAndroid Build Coastguard Worker     res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize);
3125*f6dc9357SAndroid Build Coastguard Worker     if (res == SZ_OK)
3126*f6dc9357SAndroid Build Coastguard Worker       res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen,
3127*f6dc9357SAndroid Build Coastguard Worker           writeEndMark, progress, alloc, allocBig);
3128*f6dc9357SAndroid Build Coastguard Worker   }
3129*f6dc9357SAndroid Build Coastguard Worker 
3130*f6dc9357SAndroid Build Coastguard Worker   LzmaEnc_Destroy(p, alloc, allocBig);
3131*f6dc9357SAndroid Build Coastguard Worker   return res;
3132*f6dc9357SAndroid Build Coastguard Worker }
3133*f6dc9357SAndroid Build Coastguard Worker 
3134*f6dc9357SAndroid Build Coastguard Worker 
3135*f6dc9357SAndroid Build Coastguard Worker /*
3136*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
3137*f6dc9357SAndroid Build Coastguard Worker void LzmaEnc_GetLzThreads(CLzmaEncHandle p, HANDLE lz_threads[2])
3138*f6dc9357SAndroid Build Coastguard Worker {
3139*f6dc9357SAndroid Build Coastguard Worker   GET_const_CLzmaEnc_p
3140*f6dc9357SAndroid Build Coastguard Worker   lz_threads[0] = p->matchFinderMt.hashSync.thread;
3141*f6dc9357SAndroid Build Coastguard Worker   lz_threads[1] = p->matchFinderMt.btSync.thread;
3142*f6dc9357SAndroid Build Coastguard Worker }
3143*f6dc9357SAndroid Build Coastguard Worker #endif
3144*f6dc9357SAndroid Build Coastguard Worker */
3145