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