| 1 | 
           cycrow | 
           1 | 
           /* LzmaEnc.c -- LZMA Encoder
  | 
        
        
            | 
            | 
           2 | 
           2009-02-02 : Igor Pavlov : Public domain */
  | 
        
        
            | 
            | 
           3 | 
              | 
        
        
            | 
            | 
           4 | 
           #include <string.h>
  | 
        
        
            | 
            | 
           5 | 
              | 
        
        
            | 
            | 
           6 | 
           /* #define SHOW_STAT */
  | 
        
        
            | 
            | 
           7 | 
           /* #define SHOW_STAT2 */
  | 
        
        
            | 
            | 
           8 | 
              | 
        
        
            | 
            | 
           9 | 
           #if defined(SHOW_STAT) || defined(SHOW_STAT2)
  | 
        
        
            | 
            | 
           10 | 
           #include <stdio.h>
  | 
        
        
            | 
            | 
           11 | 
           #endif
  | 
        
        
            | 
            | 
           12 | 
              | 
        
        
            | 
            | 
           13 | 
           #include "LzmaEnc.h"
  | 
        
        
            | 
            | 
           14 | 
              | 
        
        
            | 
            | 
           15 | 
           #include "LzFind.h"
  | 
        
        
            | 
            | 
           16 | 
           #ifdef COMPRESS_MF_MT
  | 
        
        
            | 
            | 
           17 | 
           #include "LzFindMt.h"
  | 
        
        
            | 
            | 
           18 | 
           #endif
  | 
        
        
            | 
            | 
           19 | 
              | 
        
        
            | 
            | 
           20 | 
           #ifdef SHOW_STAT
  | 
        
        
            | 
            | 
           21 | 
           static int ttt = 0;
  | 
        
        
            | 
            | 
           22 | 
           #endif
  | 
        
        
            | 
            | 
           23 | 
              | 
        
        
            | 
            | 
           24 | 
           #define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
  | 
        
        
            | 
            | 
           25 | 
              | 
        
        
            | 
            | 
           26 | 
           #define kBlockSize (9 << 10)
  | 
        
        
            | 
            | 
           27 | 
           #define kUnpackBlockSize (1 << 18)
  | 
        
        
            | 
            | 
           28 | 
           #define kMatchArraySize (1 << 21)
  | 
        
        
            | 
            | 
           29 | 
           #define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX)
  | 
        
        
            | 
            | 
           30 | 
              | 
        
        
            | 
            | 
           31 | 
           #define kNumMaxDirectBits (31)
  | 
        
        
            | 
            | 
           32 | 
              | 
        
        
            | 
            | 
           33 | 
           #define kNumTopBits 24
  | 
        
        
            | 
            | 
           34 | 
           #define kTopValue ((UInt32)1 << kNumTopBits)
  | 
        
        
            | 
            | 
           35 | 
              | 
        
        
            | 
            | 
           36 | 
           #define kNumBitModelTotalBits 11
  | 
        
        
            | 
            | 
           37 | 
           #define kBitModelTotal (1 << kNumBitModelTotalBits)
  | 
        
        
            | 
            | 
           38 | 
           #define kNumMoveBits 5
  | 
        
        
            | 
            | 
           39 | 
           #define kProbInitValue (kBitModelTotal >> 1)
  | 
        
        
            | 
            | 
           40 | 
              | 
        
        
            | 
            | 
           41 | 
           #define kNumMoveReducingBits 4
  | 
        
        
            | 
            | 
           42 | 
           #define kNumBitPriceShiftBits 4
  | 
        
        
            | 
            | 
           43 | 
           #define kBitPrice (1 << kNumBitPriceShiftBits)
  | 
        
        
            | 
            | 
           44 | 
              | 
        
        
            | 
            | 
           45 | 
           void LzmaEncProps_Init(CLzmaEncProps *p)
  | 
        
        
            | 
            | 
           46 | 
           {
  | 
        
        
            | 
            | 
           47 | 
             p->level = 5;
  | 
        
        
            | 
            | 
           48 | 
             p->dictSize = p->mc = 0;
  | 
        
        
            | 
            | 
           49 | 
             p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;
  | 
        
        
            | 
            | 
           50 | 
             p->writeEndMark = 0;
  | 
        
        
            | 
            | 
           51 | 
           }
  | 
        
        
            | 
            | 
           52 | 
              | 
        
        
            | 
            | 
           53 | 
           void LzmaEncProps_Normalize(CLzmaEncProps *p)
  | 
        
        
            | 
            | 
           54 | 
           {
  | 
        
        
            | 
            | 
           55 | 
             int level = p->level;
  | 
        
        
            | 
            | 
           56 | 
             if (level < 0) level = 5;
  | 
        
        
            | 
            | 
           57 | 
             p->level = level;
  | 
        
        
            | 
            | 
           58 | 
             if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));
  | 
        
        
            | 
            | 
           59 | 
             if (p->lc < 0) p->lc = 3;
  | 
        
        
            | 
            | 
           60 | 
             if (p->lp < 0) p->lp = 0;
  | 
        
        
            | 
            | 
           61 | 
             if (p->pb < 0) p->pb = 2;
  | 
        
        
            | 
            | 
           62 | 
             if (p->algo < 0) p->algo = (level < 5 ? 0 : 1);
  | 
        
        
            | 
            | 
           63 | 
             if (p->fb < 0) p->fb = (level < 7 ? 32 : 64);
  | 
        
        
            | 
            | 
           64 | 
             if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
  | 
        
        
            | 
            | 
           65 | 
             if (p->numHashBytes < 0) p->numHashBytes = 4;
  | 
        
        
            | 
            | 
           66 | 
             if (p->mc == 0)  p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1);
  | 
        
        
            | 
            | 
           67 | 
             if (p->numThreads < 0)
  | 
        
        
            | 
            | 
           68 | 
               p->numThreads =
  | 
        
        
            | 
            | 
           69 | 
                 #ifdef COMPRESS_MF_MT
  | 
        
        
            | 
            | 
           70 | 
                 ((p->btMode && p->algo) ? 2 : 1);
  | 
        
        
            | 
            | 
           71 | 
                 #else
  | 
        
        
            | 
            | 
           72 | 
                 1;
  | 
        
        
            | 
            | 
           73 | 
                 #endif
  | 
        
        
            | 
            | 
           74 | 
           }
  | 
        
        
            | 
            | 
           75 | 
              | 
        
        
            | 
            | 
           76 | 
           UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
  | 
        
        
            | 
            | 
           77 | 
           {
  | 
        
        
            | 
            | 
           78 | 
             CLzmaEncProps props = *props2;
  | 
        
        
            | 
            | 
           79 | 
             LzmaEncProps_Normalize(&props);
  | 
        
        
            | 
            | 
           80 | 
             return props.dictSize;
  | 
        
        
            | 
            | 
           81 | 
           }
  | 
        
        
            | 
            | 
           82 | 
              | 
        
        
            | 
            | 
           83 | 
           /* #define LZMA_LOG_BSR */
  | 
        
        
            | 
            | 
           84 | 
           /* Define it for Intel's CPU */
  | 
        
        
            | 
            | 
           85 | 
              | 
        
        
            | 
            | 
           86 | 
              | 
        
        
            | 
            | 
           87 | 
           #ifdef LZMA_LOG_BSR
  | 
        
        
            | 
            | 
           88 | 
              | 
        
        
            | 
            | 
           89 | 
           #define kDicLogSizeMaxCompress 30
  | 
        
        
            | 
            | 
           90 | 
              | 
        
        
            | 
            | 
           91 | 
           #define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }
  | 
        
        
            | 
            | 
           92 | 
              | 
        
        
            | 
            | 
           93 | 
           UInt32 GetPosSlot1(UInt32 pos)
  | 
        
        
            | 
            | 
           94 | 
           {
  | 
        
        
            | 
            | 
           95 | 
             UInt32 res;
  | 
        
        
            | 
            | 
           96 | 
             BSR2_RET(pos, res);
  | 
        
        
            | 
            | 
           97 | 
             return res;
  | 
        
        
            | 
            | 
           98 | 
           }
  | 
        
        
            | 
            | 
           99 | 
           #define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
  | 
        
        
            | 
            | 
           100 | 
           #define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); }
  | 
        
        
            | 
            | 
           101 | 
              | 
        
        
            | 
            | 
           102 | 
           #else
  | 
        
        
            | 
            | 
           103 | 
              | 
        
        
            | 
            | 
           104 | 
           #define kNumLogBits (9 + (int)sizeof(size_t) / 2)
  | 
        
        
            | 
            | 
           105 | 
           #define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
  | 
        
        
            | 
            | 
           106 | 
              | 
        
        
            | 
            | 
           107 | 
           void LzmaEnc_FastPosInit(Byte *g_FastPos)
  | 
        
        
            | 
            | 
           108 | 
           {
  | 
        
        
            | 
            | 
           109 | 
             int c = 2, slotFast;
  | 
        
        
            | 
            | 
           110 | 
             g_FastPos[0] = 0;
  | 
        
        
            | 
            | 
           111 | 
             g_FastPos[1] = 1;
  | 
        
        
            | 
            | 
           112 | 
              | 
        
        
            | 
            | 
           113 | 
             for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++)
  | 
        
        
            | 
            | 
           114 | 
             {
  | 
        
        
            | 
            | 
           115 | 
               UInt32 k = (1 << ((slotFast >> 1) - 1));
  | 
        
        
            | 
            | 
           116 | 
               UInt32 j;
  | 
        
        
            | 
            | 
           117 | 
               for (j = 0; j < k; j++, c++)
  | 
        
        
            | 
            | 
           118 | 
                 g_FastPos[c] = (Byte)slotFast;
  | 
        
        
            | 
            | 
           119 | 
             }
  | 
        
        
            | 
            | 
           120 | 
           }
  | 
        
        
            | 
            | 
           121 | 
              | 
        
        
            | 
            | 
           122 | 
           #define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
  | 
        
        
            | 
            | 
           123 | 
             (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
  | 
        
        
            | 
            | 
           124 | 
             res = p->g_FastPos[pos >> i] + (i * 2); }
  | 
        
        
            | 
            | 
           125 | 
           /*
  | 
        
        
            | 
            | 
           126 | 
           #define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
  | 
        
        
            | 
            | 
           127 | 
             p->g_FastPos[pos >> 6] + 12 : \
  | 
        
        
            | 
            | 
           128 | 
             p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; }
  | 
        
        
            | 
            | 
           129 | 
           */
  | 
        
        
            | 
            | 
           130 | 
              | 
        
        
            | 
            | 
           131 | 
           #define GetPosSlot1(pos) p->g_FastPos[pos]
  | 
        
        
            | 
            | 
           132 | 
           #define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
  | 
        
        
            | 
            | 
           133 | 
           #define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); }
  | 
        
        
            | 
            | 
           134 | 
              | 
        
        
            | 
            | 
           135 | 
           #endif
  | 
        
        
            | 
            | 
           136 | 
              | 
        
        
            | 
            | 
           137 | 
              | 
        
        
            | 
            | 
           138 | 
           #define LZMA_NUM_REPS 4
  | 
        
        
            | 
            | 
           139 | 
              | 
        
        
            | 
            | 
           140 | 
           typedef unsigned CState;
  | 
        
        
            | 
            | 
           141 | 
              | 
        
        
            | 
            | 
           142 | 
           typedef struct _COptimal
  | 
        
        
            | 
            | 
           143 | 
           {
  | 
        
        
            | 
            | 
           144 | 
             UInt32 price;
  | 
        
        
            | 
            | 
           145 | 
              | 
        
        
            | 
            | 
           146 | 
             CState state;
  | 
        
        
            | 
            | 
           147 | 
             int prev1IsChar;
  | 
        
        
            | 
            | 
           148 | 
             int prev2;
  | 
        
        
            | 
            | 
           149 | 
              | 
        
        
            | 
            | 
           150 | 
             UInt32 posPrev2;
  | 
        
        
            | 
            | 
           151 | 
             UInt32 backPrev2;
  | 
        
        
            | 
            | 
           152 | 
              | 
        
        
            | 
            | 
           153 | 
             UInt32 posPrev;
  | 
        
        
            | 
            | 
           154 | 
             UInt32 backPrev;
  | 
        
        
            | 
            | 
           155 | 
             UInt32 backs[LZMA_NUM_REPS];
  | 
        
        
            | 
            | 
           156 | 
           } COptimal;
  | 
        
        
            | 
            | 
           157 | 
              | 
        
        
            | 
            | 
           158 | 
           #define kNumOpts (1 << 12)
  | 
        
        
            | 
            | 
           159 | 
              | 
        
        
            | 
            | 
           160 | 
           #define kNumLenToPosStates 4
  | 
        
        
            | 
            | 
           161 | 
           #define kNumPosSlotBits 6
  | 
        
        
            | 
            | 
           162 | 
           #define kDicLogSizeMin 0
  | 
        
        
            | 
            | 
           163 | 
           #define kDicLogSizeMax 32
  | 
        
        
            | 
            | 
           164 | 
           #define kDistTableSizeMax (kDicLogSizeMax * 2)
  | 
        
        
            | 
            | 
           165 | 
              | 
        
        
            | 
            | 
           166 | 
              | 
        
        
            | 
            | 
           167 | 
           #define kNumAlignBits 4
  | 
        
        
            | 
            | 
           168 | 
           #define kAlignTableSize (1 << kNumAlignBits)
  | 
        
        
            | 
            | 
           169 | 
           #define kAlignMask (kAlignTableSize - 1)
  | 
        
        
            | 
            | 
           170 | 
              | 
        
        
            | 
            | 
           171 | 
           #define kStartPosModelIndex 4
  | 
        
        
            | 
            | 
           172 | 
           #define kEndPosModelIndex 14
  | 
        
        
            | 
            | 
           173 | 
           #define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex)
  | 
        
        
            | 
            | 
           174 | 
              | 
        
        
            | 
            | 
           175 | 
           #define kNumFullDistances (1 << (kEndPosModelIndex / 2))
  | 
        
        
            | 
            | 
           176 | 
              | 
        
        
            | 
            | 
           177 | 
           #ifdef _LZMA_PROB32
  | 
        
        
            | 
            | 
           178 | 
           #define CLzmaProb UInt32
  | 
        
        
            | 
            | 
           179 | 
           #else
  | 
        
        
            | 
            | 
           180 | 
           #define CLzmaProb UInt16
  | 
        
        
            | 
            | 
           181 | 
           #endif
  | 
        
        
            | 
            | 
           182 | 
              | 
        
        
            | 
            | 
           183 | 
           #define LZMA_PB_MAX 4
  | 
        
        
            | 
            | 
           184 | 
           #define LZMA_LC_MAX 8
  | 
        
        
            | 
            | 
           185 | 
           #define LZMA_LP_MAX 4
  | 
        
        
            | 
            | 
           186 | 
              | 
        
        
            | 
            | 
           187 | 
           #define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX)
  | 
        
        
            | 
            | 
           188 | 
              | 
        
        
            | 
            | 
           189 | 
              | 
        
        
            | 
            | 
           190 | 
           #define kLenNumLowBits 3
  | 
        
        
            | 
            | 
           191 | 
           #define kLenNumLowSymbols (1 << kLenNumLowBits)
  | 
        
        
            | 
            | 
           192 | 
           #define kLenNumMidBits 3
  | 
        
        
            | 
            | 
           193 | 
           #define kLenNumMidSymbols (1 << kLenNumMidBits)
  | 
        
        
            | 
            | 
           194 | 
           #define kLenNumHighBits 8
  | 
        
        
            | 
            | 
           195 | 
           #define kLenNumHighSymbols (1 << kLenNumHighBits)
  | 
        
        
            | 
            | 
           196 | 
              | 
        
        
            | 
            | 
           197 | 
           #define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
  | 
        
        
            | 
            | 
           198 | 
              | 
        
        
            | 
            | 
           199 | 
           #define LZMA_MATCH_LEN_MIN 2
  | 
        
        
            | 
            | 
           200 | 
           #define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1)
  | 
        
        
            | 
            | 
           201 | 
              | 
        
        
            | 
            | 
           202 | 
           #define kNumStates 12
  | 
        
        
            | 
            | 
           203 | 
              | 
        
        
            | 
            | 
           204 | 
           typedef struct
  | 
        
        
            | 
            | 
           205 | 
           {
  | 
        
        
            | 
            | 
           206 | 
             CLzmaProb choice;
  | 
        
        
            | 
            | 
           207 | 
             CLzmaProb choice2;
  | 
        
        
            | 
            | 
           208 | 
             CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits];
  | 
        
        
            | 
            | 
           209 | 
             CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits];
  | 
        
        
            | 
            | 
           210 | 
             CLzmaProb high[kLenNumHighSymbols];
  | 
        
        
            | 
            | 
           211 | 
           } CLenEnc;
  | 
        
        
            | 
            | 
           212 | 
              | 
        
        
            | 
            | 
           213 | 
           typedef struct
  | 
        
        
            | 
            | 
           214 | 
           {
  | 
        
        
            | 
            | 
           215 | 
             CLenEnc p;
  | 
        
        
            | 
            | 
           216 | 
             UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
  | 
        
        
            | 
            | 
           217 | 
             UInt32 tableSize;
  | 
        
        
            | 
            | 
           218 | 
             UInt32 counters[LZMA_NUM_PB_STATES_MAX];
  | 
        
        
            | 
            | 
           219 | 
           } CLenPriceEnc;
  | 
        
        
            | 
            | 
           220 | 
              | 
        
        
            | 
            | 
           221 | 
           typedef struct _CRangeEnc
  | 
        
        
            | 
            | 
           222 | 
           {
  | 
        
        
            | 
            | 
           223 | 
             UInt32 range;
  | 
        
        
            | 
            | 
           224 | 
             Byte cache;
  | 
        
        
            | 
            | 
           225 | 
             UInt64 low;
  | 
        
        
            | 
            | 
           226 | 
             UInt64 cacheSize;
  | 
        
        
            | 
            | 
           227 | 
             Byte *buf;
  | 
        
        
            | 
            | 
           228 | 
             Byte *bufLim;
  | 
        
        
            | 
            | 
           229 | 
             Byte *bufBase;
  | 
        
        
            | 
            | 
           230 | 
             ISeqOutStream *outStream;
  | 
        
        
            | 
            | 
           231 | 
             UInt64 processed;
  | 
        
        
            | 
            | 
           232 | 
             SRes res;
  | 
        
        
            | 
            | 
           233 | 
           } CRangeEnc;
  | 
        
        
            | 
            | 
           234 | 
              | 
        
        
            | 
            | 
           235 | 
           typedef struct _CSeqInStreamBuf
  | 
        
        
            | 
            | 
           236 | 
           {
  | 
        
        
            | 
            | 
           237 | 
             ISeqInStream funcTable;
  | 
        
        
            | 
            | 
           238 | 
             const Byte *data;
  | 
        
        
            | 
            | 
           239 | 
             SizeT rem;
  | 
        
        
            | 
            | 
           240 | 
           } CSeqInStreamBuf;
  | 
        
        
            | 
            | 
           241 | 
              | 
        
        
            | 
            | 
           242 | 
           static SRes MyRead(void *pp, void *data, size_t *size)
  | 
        
        
            | 
            | 
           243 | 
           {
  | 
        
        
            | 
            | 
           244 | 
             size_t curSize = *size;
  | 
        
        
            | 
            | 
           245 | 
             CSeqInStreamBuf *p = (CSeqInStreamBuf *)pp;
  | 
        
        
            | 
            | 
           246 | 
             if (p->rem < curSize)
  | 
        
        
            | 
            | 
           247 | 
               curSize = p->rem;
  | 
        
        
            | 
            | 
           248 | 
             memcpy(data, p->data, curSize);
  | 
        
        
            | 
            | 
           249 | 
             p->rem -= curSize;
  | 
        
        
            | 
            | 
           250 | 
             p->data += curSize;
  | 
        
        
            | 
            | 
           251 | 
             *size = curSize;
  | 
        
        
            | 
            | 
           252 | 
             return SZ_OK;
  | 
        
        
            | 
            | 
           253 | 
           }
  | 
        
        
            | 
            | 
           254 | 
              | 
        
        
            | 
            | 
           255 | 
           typedef struct
  | 
        
        
            | 
            | 
           256 | 
           {
  | 
        
        
            | 
            | 
           257 | 
             CLzmaProb *litProbs;
  | 
        
        
            | 
            | 
           258 | 
              | 
        
        
            | 
            | 
           259 | 
             CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
  | 
        
        
            | 
            | 
           260 | 
             CLzmaProb isRep[kNumStates];
  | 
        
        
            | 
            | 
           261 | 
             CLzmaProb isRepG0[kNumStates];
  | 
        
        
            | 
            | 
           262 | 
             CLzmaProb isRepG1[kNumStates];
  | 
        
        
            | 
            | 
           263 | 
             CLzmaProb isRepG2[kNumStates];
  | 
        
        
            | 
            | 
           264 | 
             CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
  | 
        
        
            | 
            | 
           265 | 
              | 
        
        
            | 
            | 
           266 | 
             CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
  | 
        
        
            | 
            | 
           267 | 
             CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
  | 
        
        
            | 
            | 
           268 | 
             CLzmaProb posAlignEncoder[1 << kNumAlignBits];
  | 
        
        
            | 
            | 
           269 | 
              | 
        
        
            | 
            | 
           270 | 
             CLenPriceEnc lenEnc;
  | 
        
        
            | 
            | 
           271 | 
             CLenPriceEnc repLenEnc;
  | 
        
        
            | 
            | 
           272 | 
              | 
        
        
            | 
            | 
           273 | 
             UInt32 reps[LZMA_NUM_REPS];
  | 
        
        
            | 
            | 
           274 | 
             UInt32 state;
  | 
        
        
            | 
            | 
           275 | 
           } CSaveState;
  | 
        
        
            | 
            | 
           276 | 
              | 
        
        
            | 
            | 
           277 | 
           typedef struct _CLzmaEnc
  | 
        
        
            | 
            | 
           278 | 
           {
  | 
        
        
            | 
            | 
           279 | 
             IMatchFinder matchFinder;
  | 
        
        
            | 
            | 
           280 | 
             void *matchFinderObj;
  | 
        
        
            | 
            | 
           281 | 
              | 
        
        
            | 
            | 
           282 | 
             #ifdef COMPRESS_MF_MT
  | 
        
        
            | 
            | 
           283 | 
             Bool mtMode;
  | 
        
        
            | 
            | 
           284 | 
             CMatchFinderMt matchFinderMt;
  | 
        
        
            | 
            | 
           285 | 
             #endif
  | 
        
        
            | 
            | 
           286 | 
              | 
        
        
            | 
            | 
           287 | 
             CMatchFinder matchFinderBase;
  | 
        
        
            | 
            | 
           288 | 
              | 
        
        
            | 
            | 
           289 | 
             #ifdef COMPRESS_MF_MT
  | 
        
        
            | 
            | 
           290 | 
             Byte pad[128];
  | 
        
        
            | 
            | 
           291 | 
             #endif
  | 
        
        
            | 
            | 
           292 | 
              | 
        
        
            | 
            | 
           293 | 
             UInt32 optimumEndIndex;
  | 
        
        
            | 
            | 
           294 | 
             UInt32 optimumCurrentIndex;
  | 
        
        
            | 
            | 
           295 | 
              | 
        
        
            | 
            | 
           296 | 
             UInt32 longestMatchLength;
  | 
        
        
            | 
            | 
           297 | 
             UInt32 numPairs;
  | 
        
        
            | 
            | 
           298 | 
             UInt32 numAvail;
  | 
        
        
            | 
            | 
           299 | 
             COptimal opt[kNumOpts];
  | 
        
        
            | 
            | 
           300 | 
              | 
        
        
            | 
            | 
           301 | 
             #ifndef LZMA_LOG_BSR
  | 
        
        
            | 
            | 
           302 | 
             Byte g_FastPos[1 << kNumLogBits];
  | 
        
        
            | 
            | 
           303 | 
             #endif
  | 
        
        
            | 
            | 
           304 | 
              | 
        
        
            | 
            | 
           305 | 
             UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
  | 
        
        
            | 
            | 
           306 | 
             UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];
  | 
        
        
            | 
            | 
           307 | 
             UInt32 numFastBytes;
  | 
        
        
            | 
            | 
           308 | 
             UInt32 additionalOffset;
  | 
        
        
            | 
            | 
           309 | 
             UInt32 reps[LZMA_NUM_REPS];
  | 
        
        
            | 
            | 
           310 | 
             UInt32 state;
  | 
        
        
            | 
            | 
           311 | 
              | 
        
        
            | 
            | 
           312 | 
             UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
  | 
        
        
            | 
            | 
           313 | 
             UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
  | 
        
        
            | 
            | 
           314 | 
             UInt32 alignPrices[kAlignTableSize];
  | 
        
        
            | 
            | 
           315 | 
             UInt32 alignPriceCount;
  | 
        
        
            | 
            | 
           316 | 
              | 
        
        
            | 
            | 
           317 | 
             UInt32 distTableSize;
  | 
        
        
            | 
            | 
           318 | 
              | 
        
        
            | 
            | 
           319 | 
             unsigned lc, lp, pb;
  | 
        
        
            | 
            | 
           320 | 
             unsigned lpMask, pbMask;
  | 
        
        
            | 
            | 
           321 | 
              | 
        
        
            | 
            | 
           322 | 
             CLzmaProb *litProbs;
  | 
        
        
            | 
            | 
           323 | 
              | 
        
        
            | 
            | 
           324 | 
             CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
  | 
        
        
            | 
            | 
           325 | 
             CLzmaProb isRep[kNumStates];
  | 
        
        
            | 
            | 
           326 | 
             CLzmaProb isRepG0[kNumStates];
  | 
        
        
            | 
            | 
           327 | 
             CLzmaProb isRepG1[kNumStates];
  | 
        
        
            | 
            | 
           328 | 
             CLzmaProb isRepG2[kNumStates];
  | 
        
        
            | 
            | 
           329 | 
             CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
  | 
        
        
            | 
            | 
           330 | 
              | 
        
        
            | 
            | 
           331 | 
             CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
  | 
        
        
            | 
            | 
           332 | 
             CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
  | 
        
        
            | 
            | 
           333 | 
             CLzmaProb posAlignEncoder[1 << kNumAlignBits];
  | 
        
        
            | 
            | 
           334 | 
              | 
        
        
            | 
            | 
           335 | 
             CLenPriceEnc lenEnc;
  | 
        
        
            | 
            | 
           336 | 
             CLenPriceEnc repLenEnc;
  | 
        
        
            | 
            | 
           337 | 
              | 
        
        
            | 
            | 
           338 | 
             unsigned lclp;
  | 
        
        
            | 
            | 
           339 | 
              | 
        
        
            | 
            | 
           340 | 
             Bool fastMode;
  | 
        
        
            | 
            | 
           341 | 
              | 
        
        
            | 
            | 
           342 | 
             CRangeEnc rc;
  | 
        
        
            | 
            | 
           343 | 
              | 
        
        
            | 
            | 
           344 | 
             Bool writeEndMark;
  | 
        
        
            | 
            | 
           345 | 
             UInt64 nowPos64;
  | 
        
        
            | 
            | 
           346 | 
             UInt32 matchPriceCount;
  | 
        
        
            | 
            | 
           347 | 
             Bool finished;
  | 
        
        
            | 
            | 
           348 | 
             Bool multiThread;
  | 
        
        
            | 
            | 
           349 | 
              | 
        
        
            | 
            | 
           350 | 
             SRes result;
  | 
        
        
            | 
            | 
           351 | 
             UInt32 dictSize;
  | 
        
        
            | 
            | 
           352 | 
             UInt32 matchFinderCycles;
  | 
        
        
            | 
            | 
           353 | 
              | 
        
        
            | 
            | 
           354 | 
             ISeqInStream *inStream;
  | 
        
        
            | 
            | 
           355 | 
             CSeqInStreamBuf seqBufInStream;
  | 
        
        
            | 
            | 
           356 | 
              | 
        
        
            | 
            | 
           357 | 
             CSaveState saveState;
  | 
        
        
            | 
            | 
           358 | 
           } CLzmaEnc;
  | 
        
        
            | 
            | 
           359 | 
              | 
        
        
            | 
            | 
           360 | 
           void LzmaEnc_SaveState(CLzmaEncHandle pp)
  | 
        
        
            | 
            | 
           361 | 
           {
  | 
        
        
            | 
            | 
           362 | 
             CLzmaEnc *p = (CLzmaEnc *)pp;
  | 
        
        
            | 
            | 
           363 | 
             CSaveState *dest = &p->saveState;
  | 
        
        
            | 
            | 
           364 | 
             int i;
  | 
        
        
            | 
            | 
           365 | 
             dest->lenEnc = p->lenEnc;
  | 
        
        
            | 
            | 
           366 | 
             dest->repLenEnc = p->repLenEnc;
  | 
        
        
            | 
            | 
           367 | 
             dest->state = p->state;
  | 
        
        
            | 
            | 
           368 | 
              | 
        
        
            | 
            | 
           369 | 
             for (i = 0; i < kNumStates; i++)
  | 
        
        
            | 
            | 
           370 | 
             {
  | 
        
        
            | 
            | 
           371 | 
               memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
  | 
        
        
            | 
            | 
           372 | 
               memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
  | 
        
        
            | 
            | 
           373 | 
             }
  | 
        
        
            | 
            | 
           374 | 
             for (i = 0; i < kNumLenToPosStates; i++)
  | 
        
        
            | 
            | 
           375 | 
               memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
  | 
        
        
            | 
            | 
           376 | 
             memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
  | 
        
        
            | 
            | 
           377 | 
             memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
  | 
        
        
            | 
            | 
           378 | 
             memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
  | 
        
        
            | 
            | 
           379 | 
             memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
  | 
        
        
            | 
            | 
           380 | 
             memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
  | 
        
        
            | 
            | 
           381 | 
             memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
  | 
        
        
            | 
            | 
           382 | 
             memcpy(dest->reps, p->reps, sizeof(p->reps));
  | 
        
        
            | 
            | 
           383 | 
             memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb));
  | 
        
        
            | 
            | 
           384 | 
           }
  | 
        
        
            | 
            | 
           385 | 
              | 
        
        
            | 
            | 
           386 | 
           void LzmaEnc_RestoreState(CLzmaEncHandle pp)
  | 
        
        
            | 
            | 
           387 | 
           {
  | 
        
        
            | 
            | 
           388 | 
             CLzmaEnc *dest = (CLzmaEnc *)pp;
  | 
        
        
            | 
            | 
           389 | 
             const CSaveState *p = &dest->saveState;
  | 
        
        
            | 
            | 
           390 | 
             int i;
  | 
        
        
            | 
            | 
           391 | 
             dest->lenEnc = p->lenEnc;
  | 
        
        
            | 
            | 
           392 | 
             dest->repLenEnc = p->repLenEnc;
  | 
        
        
            | 
            | 
           393 | 
             dest->state = p->state;
  | 
        
        
            | 
            | 
           394 | 
              | 
        
        
            | 
            | 
           395 | 
             for (i = 0; i < kNumStates; i++)
  | 
        
        
            | 
            | 
           396 | 
             {
  | 
        
        
            | 
            | 
           397 | 
               memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
  | 
        
        
            | 
            | 
           398 | 
               memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
  | 
        
        
            | 
            | 
           399 | 
             }
  | 
        
        
            | 
            | 
           400 | 
             for (i = 0; i < kNumLenToPosStates; i++)
  | 
        
        
            | 
            | 
           401 | 
               memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
  | 
        
        
            | 
            | 
           402 | 
             memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
  | 
        
        
            | 
            | 
           403 | 
             memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
  | 
        
        
            | 
            | 
           404 | 
             memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
  | 
        
        
            | 
            | 
           405 | 
             memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
  | 
        
        
            | 
            | 
           406 | 
             memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
  | 
        
        
            | 
            | 
           407 | 
             memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
  | 
        
        
            | 
            | 
           408 | 
             memcpy(dest->reps, p->reps, sizeof(p->reps));
  | 
        
        
            | 
            | 
           409 | 
             memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb));
  | 
        
        
            | 
            | 
           410 | 
           }
  | 
        
        
            | 
            | 
           411 | 
              | 
        
        
            | 
            | 
           412 | 
           SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
  | 
        
        
            | 
            | 
           413 | 
           {
  | 
        
        
            | 
            | 
           414 | 
             CLzmaEnc *p = (CLzmaEnc *)pp;
  | 
        
        
            | 
            | 
           415 | 
             CLzmaEncProps props = *props2;
  | 
        
        
            | 
            | 
           416 | 
             LzmaEncProps_Normalize(&props);
  | 
        
        
            | 
            | 
           417 | 
              | 
        
        
            | 
            | 
           418 | 
             if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||
  | 
        
        
            | 
            | 
           419 | 
                 props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30))
  | 
        
        
            | 
            | 
           420 | 
               return SZ_ERROR_PARAM;
  | 
        
        
            | 
            | 
           421 | 
             p->dictSize = props.dictSize;
  | 
        
        
            | 
            | 
           422 | 
             p->matchFinderCycles = props.mc;
  | 
        
        
            | 
            | 
           423 | 
             {
  | 
        
        
            | 
            | 
           424 | 
               unsigned fb = props.fb;
  | 
        
        
            | 
            | 
           425 | 
               if (fb < 5)
  | 
        
        
            | 
            | 
           426 | 
                 fb = 5;
  | 
        
        
            | 
            | 
           427 | 
               if (fb > LZMA_MATCH_LEN_MAX)
  | 
        
        
            | 
            | 
           428 | 
                 fb = LZMA_MATCH_LEN_MAX;
  | 
        
        
            | 
            | 
           429 | 
               p->numFastBytes = fb;
  | 
        
        
            | 
            | 
           430 | 
             }
  | 
        
        
            | 
            | 
           431 | 
             p->lc = props.lc;
  | 
        
        
            | 
            | 
           432 | 
             p->lp = props.lp;
  | 
        
        
            | 
            | 
           433 | 
             p->pb = props.pb;
  | 
        
        
            | 
            | 
           434 | 
             p->fastMode = (props.algo == 0);
  | 
        
        
            | 
            | 
           435 | 
             p->matchFinderBase.btMode = props.btMode;
  | 
        
        
            | 
            | 
           436 | 
             {
  | 
        
        
            | 
            | 
           437 | 
               UInt32 numHashBytes = 4;
  | 
        
        
            | 
            | 
           438 | 
               if (props.btMode)
  | 
        
        
            | 
            | 
           439 | 
               {
  | 
        
        
            | 
            | 
           440 | 
                 if (props.numHashBytes < 2)
  | 
        
        
            | 
            | 
           441 | 
                   numHashBytes = 2;
  | 
        
        
            | 
            | 
           442 | 
                 else if (props.numHashBytes < 4)
  | 
        
        
            | 
            | 
           443 | 
                   numHashBytes = props.numHashBytes;
  | 
        
        
            | 
            | 
           444 | 
               }
  | 
        
        
            | 
            | 
           445 | 
               p->matchFinderBase.numHashBytes = numHashBytes;
  | 
        
        
            | 
            | 
           446 | 
             }
  | 
        
        
            | 
            | 
           447 | 
              | 
        
        
            | 
            | 
           448 | 
             p->matchFinderBase.cutValue = props.mc;
  | 
        
        
            | 
            | 
           449 | 
              | 
        
        
            | 
            | 
           450 | 
             p->writeEndMark = props.writeEndMark;
  | 
        
        
            | 
            | 
           451 | 
              | 
        
        
            | 
            | 
           452 | 
             #ifdef COMPRESS_MF_MT
  | 
        
        
            | 
            | 
           453 | 
             /*
  | 
        
        
            | 
            | 
           454 | 
             if (newMultiThread != _multiThread)
  | 
        
        
            | 
            | 
           455 | 
             {
  | 
        
        
            | 
            | 
           456 | 
               ReleaseMatchFinder();
  | 
        
        
            | 
            | 
           457 | 
               _multiThread = newMultiThread;
  | 
        
        
            | 
            | 
           458 | 
             }
  | 
        
        
            | 
            | 
           459 | 
             */
  | 
        
        
            | 
            | 
           460 | 
             p->multiThread = (props.numThreads > 1);
  | 
        
        
            | 
            | 
           461 | 
             #endif
  | 
        
        
            | 
            | 
           462 | 
              | 
        
        
            | 
            | 
           463 | 
             return SZ_OK;
  | 
        
        
            | 
            | 
           464 | 
           }
  | 
        
        
            | 
            | 
           465 | 
              | 
        
        
            | 
            | 
           466 | 
           static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4,  5,  6,   4, 5};
  | 
        
        
            | 
            | 
           467 | 
           static const int kMatchNextStates[kNumStates]   = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
  | 
        
        
            | 
            | 
           468 | 
           static const int kRepNextStates[kNumStates]     = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
  | 
        
        
            | 
            | 
           469 | 
           static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
  | 
        
        
            | 
            | 
           470 | 
              | 
        
        
            | 
            | 
           471 | 
           #define IsCharState(s) ((s) < 7)
  | 
        
        
            | 
            | 
           472 | 
              | 
        
        
            | 
            | 
           473 | 
           #define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1)
  | 
        
        
            | 
            | 
           474 | 
              | 
        
        
            | 
            | 
           475 | 
           #define kInfinityPrice (1 << 30)
  | 
        
        
            | 
            | 
           476 | 
              | 
        
        
            | 
            | 
           477 | 
           static void RangeEnc_Construct(CRangeEnc *p)
  | 
        
        
            | 
            | 
           478 | 
           {
  | 
        
        
            | 
            | 
           479 | 
             p->outStream = 0;
  | 
        
        
            | 
            | 
           480 | 
             p->bufBase = 0;
  | 
        
        
            | 
            | 
           481 | 
           }
  | 
        
        
            | 
            | 
           482 | 
              | 
        
        
            | 
            | 
           483 | 
           #define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
  | 
        
        
            | 
            | 
           484 | 
              | 
        
        
            | 
            | 
           485 | 
           #define RC_BUF_SIZE (1 << 16)
  | 
        
        
            | 
            | 
           486 | 
           static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
  | 
        
        
            | 
            | 
           487 | 
           {
  | 
        
        
            | 
            | 
           488 | 
             if (p->bufBase == 0)
  | 
        
        
            | 
            | 
           489 | 
             {
  | 
        
        
            | 
            | 
           490 | 
               p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
  | 
        
        
            | 
            | 
           491 | 
               if (p->bufBase == 0)
  | 
        
        
            | 
            | 
           492 | 
                 return 0;
  | 
        
        
            | 
            | 
           493 | 
               p->bufLim = p->bufBase + RC_BUF_SIZE;
  | 
        
        
            | 
            | 
           494 | 
             }
  | 
        
        
            | 
            | 
           495 | 
             return 1;
  | 
        
        
            | 
            | 
           496 | 
           }
  | 
        
        
            | 
            | 
           497 | 
              | 
        
        
            | 
            | 
           498 | 
           static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc)
  | 
        
        
            | 
            | 
           499 | 
           {
  | 
        
        
            | 
            | 
           500 | 
             alloc->Free(alloc, p->bufBase);
  | 
        
        
            | 
            | 
           501 | 
             p->bufBase = 0;
  | 
        
        
            | 
            | 
           502 | 
           }
  | 
        
        
            | 
            | 
           503 | 
              | 
        
        
            | 
            | 
           504 | 
           static void RangeEnc_Init(CRangeEnc *p)
  | 
        
        
            | 
            | 
           505 | 
           {
  | 
        
        
            | 
            | 
           506 | 
             /* Stream.Init(); */
  | 
        
        
            | 
            | 
           507 | 
             p->low = 0;
  | 
        
        
            | 
            | 
           508 | 
             p->range = 0xFFFFFFFF;
  | 
        
        
            | 
            | 
           509 | 
             p->cacheSize = 1;
  | 
        
        
            | 
            | 
           510 | 
             p->cache = 0;
  | 
        
        
            | 
            | 
           511 | 
              | 
        
        
            | 
            | 
           512 | 
             p->buf = p->bufBase;
  | 
        
        
            | 
            | 
           513 | 
              | 
        
        
            | 
            | 
           514 | 
             p->processed = 0;
  | 
        
        
            | 
            | 
           515 | 
             p->res = SZ_OK;
  | 
        
        
            | 
            | 
           516 | 
           }
  | 
        
        
            | 
            | 
           517 | 
              | 
        
        
            | 
            | 
           518 | 
           static void RangeEnc_FlushStream(CRangeEnc *p)
  | 
        
        
            | 
            | 
           519 | 
           {
  | 
        
        
            | 
            | 
           520 | 
             size_t num;
  | 
        
        
            | 
            | 
           521 | 
             if (p->res != SZ_OK)
  | 
        
        
            | 
            | 
           522 | 
               return;
  | 
        
        
            | 
            | 
           523 | 
             num = p->buf - p->bufBase;
  | 
        
        
            | 
            | 
           524 | 
             if (num != p->outStream->Write(p->outStream, p->bufBase, num))
  | 
        
        
            | 
            | 
           525 | 
               p->res = SZ_ERROR_WRITE;
  | 
        
        
            | 
            | 
           526 | 
             p->processed += num;
  | 
        
        
            | 
            | 
           527 | 
             p->buf = p->bufBase;
  | 
        
        
            | 
            | 
           528 | 
           }
  | 
        
        
            | 
            | 
           529 | 
              | 
        
        
            | 
            | 
           530 | 
           static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)
  | 
        
        
            | 
            | 
           531 | 
           {
  | 
        
        
            | 
            | 
           532 | 
             if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0)
  | 
        
        
            | 
            | 
           533 | 
             {
  | 
        
        
            | 
            | 
           534 | 
               Byte temp = p->cache;
  | 
        
        
            | 
            | 
           535 | 
               do
  | 
        
        
            | 
            | 
           536 | 
               {
  | 
        
        
            | 
            | 
           537 | 
                 Byte *buf = p->buf;
  | 
        
        
            | 
            | 
           538 | 
                 *buf++ = (Byte)(temp + (Byte)(p->low >> 32));
  | 
        
        
            | 
            | 
           539 | 
                 p->buf = buf;
  | 
        
        
            | 
            | 
           540 | 
                 if (buf == p->bufLim)
  | 
        
        
            | 
            | 
           541 | 
                   RangeEnc_FlushStream(p);
  | 
        
        
            | 
            | 
           542 | 
                 temp = 0xFF;
  | 
        
        
            | 
            | 
           543 | 
               }
  | 
        
        
            | 
            | 
           544 | 
               while (--p->cacheSize != 0);
  | 
        
        
            | 
            | 
           545 | 
               p->cache = (Byte)((UInt32)p->low >> 24);
  | 
        
        
            | 
            | 
           546 | 
             }
  | 
        
        
            | 
            | 
           547 | 
             p->cacheSize++;
  | 
        
        
            | 
            | 
           548 | 
             p->low = (UInt32)p->low << 8;
  | 
        
        
            | 
            | 
           549 | 
           }
  | 
        
        
            | 
            | 
           550 | 
              | 
        
        
            | 
            | 
           551 | 
           static void RangeEnc_FlushData(CRangeEnc *p)
  | 
        
        
            | 
            | 
           552 | 
           {
  | 
        
        
            | 
            | 
           553 | 
             int i;
  | 
        
        
            | 
            | 
           554 | 
             for (i = 0; i < 5; i++)
  | 
        
        
            | 
            | 
           555 | 
               RangeEnc_ShiftLow(p);
  | 
        
        
            | 
            | 
           556 | 
           }
  | 
        
        
            | 
            | 
           557 | 
              | 
        
        
            | 
            | 
           558 | 
           static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits)
  | 
        
        
            | 
            | 
           559 | 
           {
  | 
        
        
            | 
            | 
           560 | 
             do
  | 
        
        
            | 
            | 
           561 | 
             {
  | 
        
        
            | 
            | 
           562 | 
               p->range >>= 1;
  | 
        
        
            | 
            | 
           563 | 
               p->low += p->range & (0 - ((value >> --numBits) & 1));
  | 
        
        
            | 
            | 
           564 | 
               if (p->range < kTopValue)
  | 
        
        
            | 
            | 
           565 | 
               {
  | 
        
        
            | 
            | 
           566 | 
                 p->range <<= 8;
  | 
        
        
            | 
            | 
           567 | 
                 RangeEnc_ShiftLow(p);
  | 
        
        
            | 
            | 
           568 | 
               }
  | 
        
        
            | 
            | 
           569 | 
             }
  | 
        
        
            | 
            | 
           570 | 
             while (numBits != 0);
  | 
        
        
            | 
            | 
           571 | 
           }
  | 
        
        
            | 
            | 
           572 | 
              | 
        
        
            | 
            | 
           573 | 
           static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol)
  | 
        
        
            | 
            | 
           574 | 
           {
  | 
        
        
            | 
            | 
           575 | 
             UInt32 ttt = *prob;
  | 
        
        
            | 
            | 
           576 | 
             UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt;
  | 
        
        
            | 
            | 
           577 | 
             if (symbol == 0)
  | 
        
        
            | 
            | 
           578 | 
             {
  | 
        
        
            | 
            | 
           579 | 
               p->range = newBound;
  | 
        
        
            | 
            | 
           580 | 
               ttt += (kBitModelTotal - ttt) >> kNumMoveBits;
  | 
        
        
            | 
            | 
           581 | 
             }
  | 
        
        
            | 
            | 
           582 | 
             else
  | 
        
        
            | 
            | 
           583 | 
             {
  | 
        
        
            | 
            | 
           584 | 
               p->low += newBound;
  | 
        
        
            | 
            | 
           585 | 
               p->range -= newBound;
  | 
        
        
            | 
            | 
           586 | 
               ttt -= ttt >> kNumMoveBits;
  | 
        
        
            | 
            | 
           587 | 
             }
  | 
        
        
            | 
            | 
           588 | 
             *prob = (CLzmaProb)ttt;
  | 
        
        
            | 
            | 
           589 | 
             if (p->range < kTopValue)
  | 
        
        
            | 
            | 
           590 | 
             {
  | 
        
        
            | 
            | 
           591 | 
               p->range <<= 8;
  | 
        
        
            | 
            | 
           592 | 
               RangeEnc_ShiftLow(p);
  | 
        
        
            | 
            | 
           593 | 
             }
  | 
        
        
            | 
            | 
           594 | 
           }
  | 
        
        
            | 
            | 
           595 | 
              | 
        
        
            | 
            | 
           596 | 
           static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol)
  | 
        
        
            | 
            | 
           597 | 
           {
  | 
        
        
            | 
            | 
           598 | 
             symbol |= 0x100;
  | 
        
        
            | 
            | 
           599 | 
             do
  | 
        
        
            | 
            | 
           600 | 
             {
  | 
        
        
            | 
            | 
           601 | 
               RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1);
  | 
        
        
            | 
            | 
           602 | 
               symbol <<= 1;
  | 
        
        
            | 
            | 
           603 | 
             }
  | 
        
        
            | 
            | 
           604 | 
             while (symbol < 0x10000);
  | 
        
        
            | 
            | 
           605 | 
           }
  | 
        
        
            | 
            | 
           606 | 
              | 
        
        
            | 
            | 
           607 | 
           static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte)
  | 
        
        
            | 
            | 
           608 | 
           {
  | 
        
        
            | 
            | 
           609 | 
             UInt32 offs = 0x100;
  | 
        
        
            | 
            | 
           610 | 
             symbol |= 0x100;
  | 
        
        
            | 
            | 
           611 | 
             do
  | 
        
        
            | 
            | 
           612 | 
             {
  | 
        
        
            | 
            | 
           613 | 
               matchByte <<= 1;
  | 
        
        
            | 
            | 
           614 | 
               RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1);
  | 
        
        
            | 
            | 
           615 | 
               symbol <<= 1;
  | 
        
        
            | 
            | 
           616 | 
               offs &= ~(matchByte ^ symbol);
  | 
        
        
            | 
            | 
           617 | 
             }
  | 
        
        
            | 
            | 
           618 | 
             while (symbol < 0x10000);
  | 
        
        
            | 
            | 
           619 | 
           }
  | 
        
        
            | 
            | 
           620 | 
              | 
        
        
            | 
            | 
           621 | 
           void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
  | 
        
        
            | 
            | 
           622 | 
           {
  | 
        
        
            | 
            | 
           623 | 
             UInt32 i;
  | 
        
        
            | 
            | 
           624 | 
             for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
  | 
        
        
            | 
            | 
           625 | 
             {
  | 
        
        
            | 
            | 
           626 | 
               const int kCyclesBits = kNumBitPriceShiftBits;
  | 
        
        
            | 
            | 
           627 | 
               UInt32 w = i;
  | 
        
        
            | 
            | 
           628 | 
               UInt32 bitCount = 0;
  | 
        
        
            | 
            | 
           629 | 
               int j;
  | 
        
        
            | 
            | 
           630 | 
               for (j = 0; j < kCyclesBits; j++)
  | 
        
        
            | 
            | 
           631 | 
               {
  | 
        
        
            | 
            | 
           632 | 
                 w = w * w;
  | 
        
        
            | 
            | 
           633 | 
                 bitCount <<= 1;
  | 
        
        
            | 
            | 
           634 | 
                 while (w >= ((UInt32)1 << 16))
  | 
        
        
            | 
            | 
           635 | 
                 {
  | 
        
        
            | 
            | 
           636 | 
                   w >>= 1;
  | 
        
        
            | 
            | 
           637 | 
                   bitCount++;
  | 
        
        
            | 
            | 
           638 | 
                 }
  | 
        
        
            | 
            | 
           639 | 
               }
  | 
        
        
            | 
            | 
           640 | 
               ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount);
  | 
        
        
            | 
            | 
           641 | 
             }
  | 
        
        
            | 
            | 
           642 | 
           }
  | 
        
        
            | 
            | 
           643 | 
              | 
        
        
            | 
            | 
           644 | 
              | 
        
        
            | 
            | 
           645 | 
           #define GET_PRICE(prob, symbol) \
  | 
        
        
            | 
            | 
           646 | 
             p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
  | 
        
        
            | 
            | 
           647 | 
              | 
        
        
            | 
            | 
           648 | 
           #define GET_PRICEa(prob, symbol) \
  | 
        
        
            | 
            | 
           649 | 
             ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
  | 
        
        
            | 
            | 
           650 | 
              | 
        
        
            | 
            | 
           651 | 
           #define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits]
  | 
        
        
            | 
            | 
           652 | 
           #define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
  | 
        
        
            | 
            | 
           653 | 
              | 
        
        
            | 
            | 
           654 | 
           #define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
  | 
        
        
            | 
            | 
           655 | 
           #define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
  | 
        
        
            | 
            | 
           656 | 
              | 
        
        
            | 
            | 
           657 | 
           static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices)
  | 
        
        
            | 
            | 
           658 | 
           {
  | 
        
        
            | 
            | 
           659 | 
             UInt32 price = 0;
  | 
        
        
            | 
            | 
           660 | 
             symbol |= 0x100;
  | 
        
        
            | 
            | 
           661 | 
             do
  | 
        
        
            | 
            | 
           662 | 
             {
  | 
        
        
            | 
            | 
           663 | 
               price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1);
  | 
        
        
            | 
            | 
           664 | 
               symbol <<= 1;
  | 
        
        
            | 
            | 
           665 | 
             }
  | 
        
        
            | 
            | 
           666 | 
             while (symbol < 0x10000);
  | 
        
        
            | 
            | 
           667 | 
             return price;
  | 
        
        
            | 
            | 
           668 | 
           }
  | 
        
        
            | 
            | 
           669 | 
              | 
        
        
            | 
            | 
           670 | 
           static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices)
  | 
        
        
            | 
            | 
           671 | 
           {
  | 
        
        
            | 
            | 
           672 | 
             UInt32 price = 0;
  | 
        
        
            | 
            | 
           673 | 
             UInt32 offs = 0x100;
  | 
        
        
            | 
            | 
           674 | 
             symbol |= 0x100;
  | 
        
        
            | 
            | 
           675 | 
             do
  | 
        
        
            | 
            | 
           676 | 
             {
  | 
        
        
            | 
            | 
           677 | 
               matchByte <<= 1;
  | 
        
        
            | 
            | 
           678 | 
               price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1);
  | 
        
        
            | 
            | 
           679 | 
               symbol <<= 1;
  | 
        
        
            | 
            | 
           680 | 
               offs &= ~(matchByte ^ symbol);
  | 
        
        
            | 
            | 
           681 | 
             }
  | 
        
        
            | 
            | 
           682 | 
             while (symbol < 0x10000);
  | 
        
        
            | 
            | 
           683 | 
             return price;
  | 
        
        
            | 
            | 
           684 | 
           }
  | 
        
        
            | 
            | 
           685 | 
              | 
        
        
            | 
            | 
           686 | 
              | 
        
        
            | 
            | 
           687 | 
           static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
  | 
        
        
            | 
            | 
           688 | 
           {
  | 
        
        
            | 
            | 
           689 | 
             UInt32 m = 1;
  | 
        
        
            | 
            | 
           690 | 
             int i;
  | 
        
        
            | 
            | 
           691 | 
             for (i = numBitLevels; i != 0;)
  | 
        
        
            | 
            | 
           692 | 
             {
  | 
        
        
            | 
            | 
           693 | 
               UInt32 bit;
  | 
        
        
            | 
            | 
           694 | 
               i--;
  | 
        
        
            | 
            | 
           695 | 
               bit = (symbol >> i) & 1;
  | 
        
        
            | 
            | 
           696 | 
               RangeEnc_EncodeBit(rc, probs + m, bit);
  | 
        
        
            | 
            | 
           697 | 
               m = (m << 1) | bit;
  | 
        
        
            | 
            | 
           698 | 
             }
  | 
        
        
            | 
            | 
           699 | 
           }
  | 
        
        
            | 
            | 
           700 | 
              | 
        
        
            | 
            | 
           701 | 
           static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
  | 
        
        
            | 
            | 
           702 | 
           {
  | 
        
        
            | 
            | 
           703 | 
             UInt32 m = 1;
  | 
        
        
            | 
            | 
           704 | 
             int i;
  | 
        
        
            | 
            | 
           705 | 
             for (i = 0; i < numBitLevels; i++)
  | 
        
        
            | 
            | 
           706 | 
             {
  | 
        
        
            | 
            | 
           707 | 
               UInt32 bit = symbol & 1;
  | 
        
        
            | 
            | 
           708 | 
               RangeEnc_EncodeBit(rc, probs + m, bit);
  | 
        
        
            | 
            | 
           709 | 
               m = (m << 1) | bit;
  | 
        
        
            | 
            | 
           710 | 
               symbol >>= 1;
  | 
        
        
            | 
            | 
           711 | 
             }
  | 
        
        
            | 
            | 
           712 | 
           }
  | 
        
        
            | 
            | 
           713 | 
              | 
        
        
            | 
            | 
           714 | 
           static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
  | 
        
        
            | 
            | 
           715 | 
           {
  | 
        
        
            | 
            | 
           716 | 
             UInt32 price = 0;
  | 
        
        
            | 
            | 
           717 | 
             symbol |= (1 << numBitLevels);
  | 
        
        
            | 
            | 
           718 | 
             while (symbol != 1)
  | 
        
        
            | 
            | 
           719 | 
             {
  | 
        
        
            | 
            | 
           720 | 
               price += GET_PRICEa(probs[symbol >> 1], symbol & 1);
  | 
        
        
            | 
            | 
           721 | 
               symbol >>= 1;
  | 
        
        
            | 
            | 
           722 | 
             }
  | 
        
        
            | 
            | 
           723 | 
             return price;
  | 
        
        
            | 
            | 
           724 | 
           }
  | 
        
        
            | 
            | 
           725 | 
              | 
        
        
            | 
            | 
           726 | 
           static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
  | 
        
        
            | 
            | 
           727 | 
           {
  | 
        
        
            | 
            | 
           728 | 
             UInt32 price = 0;
  | 
        
        
            | 
            | 
           729 | 
             UInt32 m = 1;
  | 
        
        
            | 
            | 
           730 | 
             int i;
  | 
        
        
            | 
            | 
           731 | 
             for (i = numBitLevels; i != 0; i--)
  | 
        
        
            | 
            | 
           732 | 
             {
  | 
        
        
            | 
            | 
           733 | 
               UInt32 bit = symbol & 1;
  | 
        
        
            | 
            | 
           734 | 
               symbol >>= 1;
  | 
        
        
            | 
            | 
           735 | 
               price += GET_PRICEa(probs[m], bit);
  | 
        
        
            | 
            | 
           736 | 
               m = (m << 1) | bit;
  | 
        
        
            | 
            | 
           737 | 
             }
  | 
        
        
            | 
            | 
           738 | 
             return price;
  | 
        
        
            | 
            | 
           739 | 
           }
  | 
        
        
            | 
            | 
           740 | 
              | 
        
        
            | 
            | 
           741 | 
              | 
        
        
            | 
            | 
           742 | 
           static void LenEnc_Init(CLenEnc *p)
  | 
        
        
            | 
            | 
           743 | 
           {
  | 
        
        
            | 
            | 
           744 | 
             unsigned i;
  | 
        
        
            | 
            | 
           745 | 
             p->choice = p->choice2 = kProbInitValue;
  | 
        
        
            | 
            | 
           746 | 
             for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++)
  | 
        
        
            | 
            | 
           747 | 
               p->low[i] = kProbInitValue;
  | 
        
        
            | 
            | 
           748 | 
             for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++)
  | 
        
        
            | 
            | 
           749 | 
               p->mid[i] = kProbInitValue;
  | 
        
        
            | 
            | 
           750 | 
             for (i = 0; i < kLenNumHighSymbols; i++)
  | 
        
        
            | 
            | 
           751 | 
               p->high[i] = kProbInitValue;
  | 
        
        
            | 
            | 
           752 | 
           }
  | 
        
        
            | 
            | 
           753 | 
              | 
        
        
            | 
            | 
           754 | 
           static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState)
  | 
        
        
            | 
            | 
           755 | 
           {
  | 
        
        
            | 
            | 
           756 | 
             if (symbol < kLenNumLowSymbols)
  | 
        
        
            | 
            | 
           757 | 
             {
  | 
        
        
            | 
            | 
           758 | 
               RangeEnc_EncodeBit(rc, &p->choice, 0);
  | 
        
        
            | 
            | 
           759 | 
               RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol);
  | 
        
        
            | 
            | 
           760 | 
             }
  | 
        
        
            | 
            | 
           761 | 
             else
  | 
        
        
            | 
            | 
           762 | 
             {
  | 
        
        
            | 
            | 
           763 | 
               RangeEnc_EncodeBit(rc, &p->choice, 1);
  | 
        
        
            | 
            | 
           764 | 
               if (symbol < kLenNumLowSymbols + kLenNumMidSymbols)
  | 
        
        
            | 
            | 
           765 | 
               {
  | 
        
        
            | 
            | 
           766 | 
                 RangeEnc_EncodeBit(rc, &p->choice2, 0);
  | 
        
        
            | 
            | 
           767 | 
                 RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols);
  | 
        
        
            | 
            | 
           768 | 
               }
  | 
        
        
            | 
            | 
           769 | 
               else
  | 
        
        
            | 
            | 
           770 | 
               {
  | 
        
        
            | 
            | 
           771 | 
                 RangeEnc_EncodeBit(rc, &p->choice2, 1);
  | 
        
        
            | 
            | 
           772 | 
                 RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols);
  | 
        
        
            | 
            | 
           773 | 
               }
  | 
        
        
            | 
            | 
           774 | 
             }
  | 
        
        
            | 
            | 
           775 | 
           }
  | 
        
        
            | 
            | 
           776 | 
              | 
        
        
            | 
            | 
           777 | 
           static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices)
  | 
        
        
            | 
            | 
           778 | 
           {
  | 
        
        
            | 
            | 
           779 | 
             UInt32 a0 = GET_PRICE_0a(p->choice);
  | 
        
        
            | 
            | 
           780 | 
             UInt32 a1 = GET_PRICE_1a(p->choice);
  | 
        
        
            | 
            | 
           781 | 
             UInt32 b0 = a1 + GET_PRICE_0a(p->choice2);
  | 
        
        
            | 
            | 
           782 | 
             UInt32 b1 = a1 + GET_PRICE_1a(p->choice2);
  | 
        
        
            | 
            | 
           783 | 
             UInt32 i = 0;
  | 
        
        
            | 
            | 
           784 | 
             for (i = 0; i < kLenNumLowSymbols; i++)
  | 
        
        
            | 
            | 
           785 | 
             {
  | 
        
        
            | 
            | 
           786 | 
               if (i >= numSymbols)
  | 
        
        
            | 
            | 
           787 | 
                 return;
  | 
        
        
            | 
            | 
           788 | 
               prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices);
  | 
        
        
            | 
            | 
           789 | 
             }
  | 
        
        
            | 
            | 
           790 | 
             for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++)
  | 
        
        
            | 
            | 
           791 | 
             {
  | 
        
        
            | 
            | 
           792 | 
               if (i >= numSymbols)
  | 
        
        
            | 
            | 
           793 | 
                 return;
  | 
        
        
            | 
            | 
           794 | 
               prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices);
  | 
        
        
            | 
            | 
           795 | 
             }
  | 
        
        
            | 
            | 
           796 | 
             for (; i < numSymbols; i++)
  | 
        
        
            | 
            | 
           797 | 
               prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices);
  | 
        
        
            | 
            | 
           798 | 
           }
  | 
        
        
            | 
            | 
           799 | 
              | 
        
        
            | 
            | 
           800 | 
           static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices)
  | 
        
        
            | 
            | 
           801 | 
           {
  | 
        
        
            | 
            | 
           802 | 
             LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices);
  | 
        
        
            | 
            | 
           803 | 
             p->counters[posState] = p->tableSize;
  | 
        
        
            | 
            | 
           804 | 
           }
  | 
        
        
            | 
            | 
           805 | 
              | 
        
        
            | 
            | 
           806 | 
           static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices)
  | 
        
        
            | 
            | 
           807 | 
           {
  | 
        
        
            | 
            | 
           808 | 
             UInt32 posState;
  | 
        
        
            | 
            | 
           809 | 
             for (posState = 0; posState < numPosStates; posState++)
  | 
        
        
            | 
            | 
           810 | 
               LenPriceEnc_UpdateTable(p, posState, ProbPrices);
  | 
        
        
            | 
            | 
           811 | 
           }
  | 
        
        
            | 
            | 
           812 | 
              | 
        
        
            | 
            | 
           813 | 
           static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices)
  | 
        
        
            | 
            | 
           814 | 
           {
  | 
        
        
            | 
            | 
           815 | 
             LenEnc_Encode(&p->p, rc, symbol, posState);
  | 
        
        
            | 
            | 
           816 | 
             if (updatePrice)
  | 
        
        
            | 
            | 
           817 | 
               if (--p->counters[posState] == 0)
  | 
        
        
            | 
            | 
           818 | 
                 LenPriceEnc_UpdateTable(p, posState, ProbPrices);
  | 
        
        
            | 
            | 
           819 | 
           }
  | 
        
        
            | 
            | 
           820 | 
              | 
        
        
            | 
            | 
           821 | 
              | 
        
        
            | 
            | 
           822 | 
              | 
        
        
            | 
            | 
           823 | 
              | 
        
        
            | 
            | 
           824 | 
           static void MovePos(CLzmaEnc *p, UInt32 num)
  | 
        
        
            | 
            | 
           825 | 
           {
  | 
        
        
            | 
            | 
           826 | 
             #ifdef SHOW_STAT
  | 
        
        
            | 
            | 
           827 | 
             ttt += num;
  | 
        
        
            | 
            | 
           828 | 
             printf("\n MovePos %d", num);
  | 
        
        
            | 
            | 
           829 | 
             #endif
  | 
        
        
            | 
            | 
           830 | 
             if (num != 0)
  | 
        
        
            | 
            | 
           831 | 
             {
  | 
        
        
            | 
            | 
           832 | 
               p->additionalOffset += num;
  | 
        
        
            | 
            | 
           833 | 
               p->matchFinder.Skip(p->matchFinderObj, num);
  | 
        
        
            | 
            | 
           834 | 
             }
  | 
        
        
            | 
            | 
           835 | 
           }
  | 
        
        
            | 
            | 
           836 | 
              | 
        
        
            | 
            | 
           837 | 
           static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
  | 
        
        
            | 
            | 
           838 | 
           {
  | 
        
        
            | 
            | 
           839 | 
             UInt32 lenRes = 0, numPairs;
  | 
        
        
            | 
            | 
           840 | 
             p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
  | 
        
        
            | 
            | 
           841 | 
             numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
  | 
        
        
            | 
            | 
           842 | 
             #ifdef SHOW_STAT
  | 
        
        
            | 
            | 
           843 | 
             printf("\n i = %d numPairs = %d    ", ttt, numPairs / 2);
  | 
        
        
            | 
            | 
           844 | 
             ttt++;
  | 
        
        
            | 
            | 
           845 | 
             {
  | 
        
        
            | 
            | 
           846 | 
               UInt32 i;
  | 
        
        
            | 
            | 
           847 | 
               for (i = 0; i < numPairs; i += 2)
  | 
        
        
            | 
            | 
           848 | 
                 printf("%2d %6d   | ", p->matches[i], p->matches[i + 1]);
  | 
        
        
            | 
            | 
           849 | 
             }
  | 
        
        
            | 
            | 
           850 | 
             #endif
  | 
        
        
            | 
            | 
           851 | 
             if (numPairs > 0)
  | 
        
        
            | 
            | 
           852 | 
             {
  | 
        
        
            | 
            | 
           853 | 
               lenRes = p->matches[numPairs - 2];
  | 
        
        
            | 
            | 
           854 | 
               if (lenRes == p->numFastBytes)
  | 
        
        
            | 
            | 
           855 | 
               {
  | 
        
        
            | 
            | 
           856 | 
                 const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
  | 
        
        
            | 
            | 
           857 | 
                 UInt32 distance = p->matches[numPairs - 1] + 1;
  | 
        
        
            | 
            | 
           858 | 
                 UInt32 numAvail = p->numAvail;
  | 
        
        
            | 
            | 
           859 | 
                 if (numAvail > LZMA_MATCH_LEN_MAX)
  | 
        
        
            | 
            | 
           860 | 
                   numAvail = LZMA_MATCH_LEN_MAX;
  | 
        
        
            | 
            | 
           861 | 
                 {
  | 
        
        
            | 
            | 
           862 | 
                   const Byte *pby2 = pby - distance;
  | 
        
        
            | 
            | 
           863 | 
                   for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++);
  | 
        
        
            | 
            | 
           864 | 
                 }
  | 
        
        
            | 
            | 
           865 | 
               }
  | 
        
        
            | 
            | 
           866 | 
             }
  | 
        
        
            | 
            | 
           867 | 
             p->additionalOffset++;
  | 
        
        
            | 
            | 
           868 | 
             *numDistancePairsRes = numPairs;
  | 
        
        
            | 
            | 
           869 | 
             return lenRes;
  | 
        
        
            | 
            | 
           870 | 
           }
  | 
        
        
            | 
            | 
           871 | 
              | 
        
        
            | 
            | 
           872 | 
              | 
        
        
            | 
            | 
           873 | 
           #define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False;
  | 
        
        
            | 
            | 
           874 | 
           #define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False;
  | 
        
        
            | 
            | 
           875 | 
           #define IsShortRep(p) ((p)->backPrev == 0)
  | 
        
        
            | 
            | 
           876 | 
              | 
        
        
            | 
            | 
           877 | 
           static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState)
  | 
        
        
            | 
            | 
           878 | 
           {
  | 
        
        
            | 
            | 
           879 | 
             return
  | 
        
        
            | 
            | 
           880 | 
               GET_PRICE_0(p->isRepG0[state]) +
  | 
        
        
            | 
            | 
           881 | 
               GET_PRICE_0(p->isRep0Long[state][posState]);
  | 
        
        
            | 
            | 
           882 | 
           }
  | 
        
        
            | 
            | 
           883 | 
              | 
        
        
            | 
            | 
           884 | 
           static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState)
  | 
        
        
            | 
            | 
           885 | 
           {
  | 
        
        
            | 
            | 
           886 | 
             UInt32 price;
  | 
        
        
            | 
            | 
           887 | 
             if (repIndex == 0)
  | 
        
        
            | 
            | 
           888 | 
             {
  | 
        
        
            | 
            | 
           889 | 
               price = GET_PRICE_0(p->isRepG0[state]);
  | 
        
        
            | 
            | 
           890 | 
               price += GET_PRICE_1(p->isRep0Long[state][posState]);
  | 
        
        
            | 
            | 
           891 | 
             }
  | 
        
        
            | 
            | 
           892 | 
             else
  | 
        
        
            | 
            | 
           893 | 
             {
  | 
        
        
            | 
            | 
           894 | 
               price = GET_PRICE_1(p->isRepG0[state]);
  | 
        
        
            | 
            | 
           895 | 
               if (repIndex == 1)
  | 
        
        
            | 
            | 
           896 | 
                 price += GET_PRICE_0(p->isRepG1[state]);
  | 
        
        
            | 
            | 
           897 | 
               else
  | 
        
        
            | 
            | 
           898 | 
               {
  | 
        
        
            | 
            | 
           899 | 
                 price += GET_PRICE_1(p->isRepG1[state]);
  | 
        
        
            | 
            | 
           900 | 
                 price += GET_PRICE(p->isRepG2[state], repIndex - 2);
  | 
        
        
            | 
            | 
           901 | 
               }
  | 
        
        
            | 
            | 
           902 | 
             }
  | 
        
        
            | 
            | 
           903 | 
             return price;
  | 
        
        
            | 
            | 
           904 | 
           }
  | 
        
        
            | 
            | 
           905 | 
              | 
        
        
            | 
            | 
           906 | 
           static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState)
  | 
        
        
            | 
            | 
           907 | 
           {
  | 
        
        
            | 
            | 
           908 | 
             return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] +
  | 
        
        
            | 
            | 
           909 | 
               GetPureRepPrice(p, repIndex, state, posState);
  | 
        
        
            | 
            | 
           910 | 
           }
  | 
        
        
            | 
            | 
           911 | 
              | 
        
        
            | 
            | 
           912 | 
           static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
  | 
        
        
            | 
            | 
           913 | 
           {
  | 
        
        
            | 
            | 
           914 | 
             UInt32 posMem = p->opt[cur].posPrev;
  | 
        
        
            | 
            | 
           915 | 
             UInt32 backMem = p->opt[cur].backPrev;
  | 
        
        
            | 
            | 
           916 | 
             p->optimumEndIndex = cur;
  | 
        
        
            | 
            | 
           917 | 
             do
  | 
        
        
            | 
            | 
           918 | 
             {
  | 
        
        
            | 
            | 
           919 | 
               if (p->opt[cur].prev1IsChar)
  | 
        
        
            | 
            | 
           920 | 
               {
  | 
        
        
            | 
            | 
           921 | 
                 MakeAsChar(&p->opt[posMem])
  | 
        
        
            | 
            | 
           922 | 
                 p->opt[posMem].posPrev = posMem - 1;
  | 
        
        
            | 
            | 
           923 | 
                 if (p->opt[cur].prev2)
  | 
        
        
            | 
            | 
           924 | 
                 {
  | 
        
        
            | 
            | 
           925 | 
                   p->opt[posMem - 1].prev1IsChar = False;
  | 
        
        
            | 
            | 
           926 | 
                   p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2;
  | 
        
        
            | 
            | 
           927 | 
                   p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2;
  | 
        
        
            | 
            | 
           928 | 
                 }
  | 
        
        
            | 
            | 
           929 | 
               }
  | 
        
        
            | 
            | 
           930 | 
               {
  | 
        
        
            | 
            | 
           931 | 
                 UInt32 posPrev = posMem;
  | 
        
        
            | 
            | 
           932 | 
                 UInt32 backCur = backMem;
  | 
        
        
            | 
            | 
           933 | 
              | 
        
        
            | 
            | 
           934 | 
                 backMem = p->opt[posPrev].backPrev;
  | 
        
        
            | 
            | 
           935 | 
                 posMem = p->opt[posPrev].posPrev;
  | 
        
        
            | 
            | 
           936 | 
              | 
        
        
            | 
            | 
           937 | 
                 p->opt[posPrev].backPrev = backCur;
  | 
        
        
            | 
            | 
           938 | 
                 p->opt[posPrev].posPrev = cur;
  | 
        
        
            | 
            | 
           939 | 
                 cur = posPrev;
  | 
        
        
            | 
            | 
           940 | 
               }
  | 
        
        
            | 
            | 
           941 | 
             }
  | 
        
        
            | 
            | 
           942 | 
             while (cur != 0);
  | 
        
        
            | 
            | 
           943 | 
             *backRes = p->opt[0].backPrev;
  | 
        
        
            | 
            | 
           944 | 
             p->optimumCurrentIndex  = p->opt[0].posPrev;
  | 
        
        
            | 
            | 
           945 | 
             return p->optimumCurrentIndex;
  | 
        
        
            | 
            | 
           946 | 
           }
  | 
        
        
            | 
            | 
           947 | 
              | 
        
        
            | 
            | 
           948 | 
           #define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300)
  | 
        
        
            | 
            | 
           949 | 
              | 
        
        
            | 
            | 
           950 | 
           static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
  | 
        
        
            | 
            | 
           951 | 
           {
  | 
        
        
            | 
            | 
           952 | 
             UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur;
  | 
        
        
            | 
            | 
           953 | 
             UInt32 matchPrice, repMatchPrice, normalMatchPrice;
  | 
        
        
            | 
            | 
           954 | 
             UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS];
  | 
        
        
            | 
            | 
           955 | 
             UInt32 *matches;
  | 
        
        
            | 
            | 
           956 | 
             const Byte *data;
  | 
        
        
            | 
            | 
           957 | 
             Byte curByte, matchByte;
  | 
        
        
            | 
            | 
           958 | 
             if (p->optimumEndIndex != p->optimumCurrentIndex)
  | 
        
        
            | 
            | 
           959 | 
             {
  | 
        
        
            | 
            | 
           960 | 
               const COptimal *opt = &p->opt[p->optimumCurrentIndex];
  | 
        
        
            | 
            | 
           961 | 
               UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex;
  | 
        
        
            | 
            | 
           962 | 
               *backRes = opt->backPrev;
  | 
        
        
            | 
            | 
           963 | 
               p->optimumCurrentIndex = opt->posPrev;
  | 
        
        
            | 
            | 
           964 | 
               return lenRes;
  | 
        
        
            | 
            | 
           965 | 
             }
  | 
        
        
            | 
            | 
           966 | 
             p->optimumCurrentIndex = p->optimumEndIndex = 0;
  | 
        
        
            | 
            | 
           967 | 
              | 
        
        
            | 
            | 
           968 | 
             if (p->additionalOffset == 0)
  | 
        
        
            | 
            | 
           969 | 
               mainLen = ReadMatchDistances(p, &numPairs);
  | 
        
        
            | 
            | 
           970 | 
             else
  | 
        
        
            | 
            | 
           971 | 
             {
  | 
        
        
            | 
            | 
           972 | 
               mainLen = p->longestMatchLength;
  | 
        
        
            | 
            | 
           973 | 
               numPairs = p->numPairs;
  | 
        
        
            | 
            | 
           974 | 
             }
  | 
        
        
            | 
            | 
           975 | 
              | 
        
        
            | 
            | 
           976 | 
             numAvail = p->numAvail;
  | 
        
        
            | 
            | 
           977 | 
             if (numAvail < 2)
  | 
        
        
            | 
            | 
           978 | 
             {
  | 
        
        
            | 
            | 
           979 | 
               *backRes = (UInt32)(-1);
  | 
        
        
            | 
            | 
           980 | 
               return 1;
  | 
        
        
            | 
            | 
           981 | 
             }
  | 
        
        
            | 
            | 
           982 | 
             if (numAvail > LZMA_MATCH_LEN_MAX)
  | 
        
        
            | 
            | 
           983 | 
               numAvail = LZMA_MATCH_LEN_MAX;
  | 
        
        
            | 
            | 
           984 | 
              | 
        
        
            | 
            | 
           985 | 
             data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
  | 
        
        
            | 
            | 
           986 | 
             repMaxIndex = 0;
  | 
        
        
            | 
            | 
           987 | 
             for (i = 0; i < LZMA_NUM_REPS; i++)
  | 
        
        
            | 
            | 
           988 | 
             {
  | 
        
        
            | 
            | 
           989 | 
               UInt32 lenTest;
  | 
        
        
            | 
            | 
           990 | 
               const Byte *data2;
  | 
        
        
            | 
            | 
           991 | 
               reps[i] = p->reps[i];
  | 
        
        
            | 
            | 
           992 | 
               data2 = data - (reps[i] + 1);
  | 
        
        
            | 
            | 
           993 | 
               if (data[0] != data2[0] || data[1] != data2[1])
  | 
        
        
            | 
            | 
           994 | 
               {
  | 
        
        
            | 
            | 
           995 | 
                 repLens[i] = 0;
  | 
        
        
            | 
            | 
           996 | 
                 continue;
  | 
        
        
            | 
            | 
           997 | 
               }
  | 
        
        
            | 
            | 
           998 | 
               for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
  | 
        
        
            | 
            | 
           999 | 
               repLens[i] = lenTest;
  | 
        
        
            | 
            | 
           1000 | 
               if (lenTest > repLens[repMaxIndex])
  | 
        
        
            | 
            | 
           1001 | 
                 repMaxIndex = i;
  | 
        
        
            | 
            | 
           1002 | 
             }
  | 
        
        
            | 
            | 
           1003 | 
             if (repLens[repMaxIndex] >= p->numFastBytes)
  | 
        
        
            | 
            | 
           1004 | 
             {
  | 
        
        
            | 
            | 
           1005 | 
               UInt32 lenRes;
  | 
        
        
            | 
            | 
           1006 | 
               *backRes = repMaxIndex;
  | 
        
        
            | 
            | 
           1007 | 
               lenRes = repLens[repMaxIndex];
  | 
        
        
            | 
            | 
           1008 | 
               MovePos(p, lenRes - 1);
  | 
        
        
            | 
            | 
           1009 | 
               return lenRes;
  | 
        
        
            | 
            | 
           1010 | 
             }
  | 
        
        
            | 
            | 
           1011 | 
              | 
        
        
            | 
            | 
           1012 | 
             matches = p->matches;
  | 
        
        
            | 
            | 
           1013 | 
             if (mainLen >= p->numFastBytes)
  | 
        
        
            | 
            | 
           1014 | 
             {
  | 
        
        
            | 
            | 
           1015 | 
               *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
  | 
        
        
            | 
            | 
           1016 | 
               MovePos(p, mainLen - 1);
  | 
        
        
            | 
            | 
           1017 | 
               return mainLen;
  | 
        
        
            | 
            | 
           1018 | 
             }
  | 
        
        
            | 
            | 
           1019 | 
             curByte = *data;
  | 
        
        
            | 
            | 
           1020 | 
             matchByte = *(data - (reps[0] + 1));
  | 
        
        
            | 
            | 
           1021 | 
              | 
        
        
            | 
            | 
           1022 | 
             if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2)
  | 
        
        
            | 
            | 
           1023 | 
             {
  | 
        
        
            | 
            | 
           1024 | 
               *backRes = (UInt32)-1;
  | 
        
        
            | 
            | 
           1025 | 
               return 1;
  | 
        
        
            | 
            | 
           1026 | 
             }
  | 
        
        
            | 
            | 
           1027 | 
              | 
        
        
            | 
            | 
           1028 | 
             p->opt[0].state = (CState)p->state;
  | 
        
        
            | 
            | 
           1029 | 
              | 
        
        
            | 
            | 
           1030 | 
             posState = (position & p->pbMask);
  | 
        
        
            | 
            | 
           1031 | 
              | 
        
        
            | 
            | 
           1032 | 
             {
  | 
        
        
            | 
            | 
           1033 | 
               const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
  | 
        
        
            | 
            | 
           1034 | 
               p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) +
  | 
        
        
            | 
            | 
           1035 | 
                   (!IsCharState(p->state) ?
  | 
        
        
            | 
            | 
           1036 | 
                     LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
  | 
        
        
            | 
            | 
           1037 | 
                     LitEnc_GetPrice(probs, curByte, p->ProbPrices));
  | 
        
        
            | 
            | 
           1038 | 
             }
  | 
        
        
            | 
            | 
           1039 | 
              | 
        
        
            | 
            | 
           1040 | 
             MakeAsChar(&p->opt[1]);
  | 
        
        
            | 
            | 
           1041 | 
              | 
        
        
            | 
            | 
           1042 | 
             matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]);
  | 
        
        
            | 
            | 
           1043 | 
             repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]);
  | 
        
        
            | 
            | 
           1044 | 
              | 
        
        
            | 
            | 
           1045 | 
             if (matchByte == curByte)
  | 
        
        
            | 
            | 
           1046 | 
             {
  | 
        
        
            | 
            | 
           1047 | 
               UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState);
  | 
        
        
            | 
            | 
           1048 | 
               if (shortRepPrice < p->opt[1].price)
  | 
        
        
            | 
            | 
           1049 | 
               {
  | 
        
        
            | 
            | 
           1050 | 
                 p->opt[1].price = shortRepPrice;
  | 
        
        
            | 
            | 
           1051 | 
                 MakeAsShortRep(&p->opt[1]);
  | 
        
        
            | 
            | 
           1052 | 
               }
  | 
        
        
            | 
            | 
           1053 | 
             }
  | 
        
        
            | 
            | 
           1054 | 
             lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]);
  | 
        
        
            | 
            | 
           1055 | 
              | 
        
        
            | 
            | 
           1056 | 
             if (lenEnd < 2)
  | 
        
        
            | 
            | 
           1057 | 
             {
  | 
        
        
            | 
            | 
           1058 | 
               *backRes = p->opt[1].backPrev;
  | 
        
        
            | 
            | 
           1059 | 
               return 1;
  | 
        
        
            | 
            | 
           1060 | 
             }
  | 
        
        
            | 
            | 
           1061 | 
              | 
        
        
            | 
            | 
           1062 | 
             p->opt[1].posPrev = 0;
  | 
        
        
            | 
            | 
           1063 | 
             for (i = 0; i < LZMA_NUM_REPS; i++)
  | 
        
        
            | 
            | 
           1064 | 
               p->opt[0].backs[i] = reps[i];
  | 
        
        
            | 
            | 
           1065 | 
              | 
        
        
            | 
            | 
           1066 | 
             len = lenEnd;
  | 
        
        
            | 
            | 
           1067 | 
             do
  | 
        
        
            | 
            | 
           1068 | 
               p->opt[len--].price = kInfinityPrice;
  | 
        
        
            | 
            | 
           1069 | 
             while (len >= 2);
  | 
        
        
            | 
            | 
           1070 | 
              | 
        
        
            | 
            | 
           1071 | 
             for (i = 0; i < LZMA_NUM_REPS; i++)
  | 
        
        
            | 
            | 
           1072 | 
             {
  | 
        
        
            | 
            | 
           1073 | 
               UInt32 repLen = repLens[i];
  | 
        
        
            | 
            | 
           1074 | 
               UInt32 price;
  | 
        
        
            | 
            | 
           1075 | 
               if (repLen < 2)
  | 
        
        
            | 
            | 
           1076 | 
                 continue;
  | 
        
        
            | 
            | 
           1077 | 
               price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState);
  | 
        
        
            | 
            | 
           1078 | 
               do
  | 
        
        
            | 
            | 
           1079 | 
               {
  | 
        
        
            | 
            | 
           1080 | 
                 UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2];
  | 
        
        
            | 
            | 
           1081 | 
                 COptimal *opt = &p->opt[repLen];
  | 
        
        
            | 
            | 
           1082 | 
                 if (curAndLenPrice < opt->price)
  | 
        
        
            | 
            | 
           1083 | 
                 {
  | 
        
        
            | 
            | 
           1084 | 
                   opt->price = curAndLenPrice;
  | 
        
        
            | 
            | 
           1085 | 
                   opt->posPrev = 0;
  | 
        
        
            | 
            | 
           1086 | 
                   opt->backPrev = i;
  | 
        
        
            | 
            | 
           1087 | 
                   opt->prev1IsChar = False;
  | 
        
        
            | 
            | 
           1088 | 
                 }
  | 
        
        
            | 
            | 
           1089 | 
               }
  | 
        
        
            | 
            | 
           1090 | 
               while (--repLen >= 2);
  | 
        
        
            | 
            | 
           1091 | 
             }
  | 
        
        
            | 
            | 
           1092 | 
              | 
        
        
            | 
            | 
           1093 | 
             normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]);
  | 
        
        
            | 
            | 
           1094 | 
              | 
        
        
            | 
            | 
           1095 | 
             len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
  | 
        
        
            | 
            | 
           1096 | 
             if (len <= mainLen)
  | 
        
        
            | 
            | 
           1097 | 
             {
  | 
        
        
            | 
            | 
           1098 | 
               UInt32 offs = 0;
  | 
        
        
            | 
            | 
           1099 | 
               while (len > matches[offs])
  | 
        
        
            | 
            | 
           1100 | 
                 offs += 2;
  | 
        
        
            | 
            | 
           1101 | 
               for (; ; len++)
  | 
        
        
            | 
            | 
           1102 | 
               {
  | 
        
        
            | 
            | 
           1103 | 
                 COptimal *opt;
  | 
        
        
            | 
            | 
           1104 | 
                 UInt32 distance = matches[offs + 1];
  | 
        
        
            | 
            | 
           1105 | 
              | 
        
        
            | 
            | 
           1106 | 
                 UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN];
  | 
        
        
            | 
            | 
           1107 | 
                 UInt32 lenToPosState = GetLenToPosState(len);
  | 
        
        
            | 
            | 
           1108 | 
                 if (distance < kNumFullDistances)
  | 
        
        
            | 
            | 
           1109 | 
                   curAndLenPrice += p->distancesPrices[lenToPosState][distance];
  | 
        
        
            | 
            | 
           1110 | 
                 else
  | 
        
        
            | 
            | 
           1111 | 
                 {
  | 
        
        
            | 
            | 
           1112 | 
                   UInt32 slot;
  | 
        
        
            | 
            | 
           1113 | 
                   GetPosSlot2(distance, slot);
  | 
        
        
            | 
            | 
           1114 | 
                   curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot];
  | 
        
        
            | 
            | 
           1115 | 
                 }
  | 
        
        
            | 
            | 
           1116 | 
                 opt = &p->opt[len];
  | 
        
        
            | 
            | 
           1117 | 
                 if (curAndLenPrice < opt->price)
  | 
        
        
            | 
            | 
           1118 | 
                 {
  | 
        
        
            | 
            | 
           1119 | 
                   opt->price = curAndLenPrice;
  | 
        
        
            | 
            | 
           1120 | 
                   opt->posPrev = 0;
  | 
        
        
            | 
            | 
           1121 | 
                   opt->backPrev = distance + LZMA_NUM_REPS;
  | 
        
        
            | 
            | 
           1122 | 
                   opt->prev1IsChar = False;
  | 
        
        
            | 
            | 
           1123 | 
                 }
  | 
        
        
            | 
            | 
           1124 | 
                 if (len == matches[offs])
  | 
        
        
            | 
            | 
           1125 | 
                 {
  | 
        
        
            | 
            | 
           1126 | 
                   offs += 2;
  | 
        
        
            | 
            | 
           1127 | 
                   if (offs == numPairs)
  | 
        
        
            | 
            | 
           1128 | 
                     break;
  | 
        
        
            | 
            | 
           1129 | 
                 }
  | 
        
        
            | 
            | 
           1130 | 
               }
  | 
        
        
            | 
            | 
           1131 | 
             }
  | 
        
        
            | 
            | 
           1132 | 
              | 
        
        
            | 
            | 
           1133 | 
             cur = 0;
  | 
        
        
            | 
            | 
           1134 | 
              | 
        
        
            | 
            | 
           1135 | 
               #ifdef SHOW_STAT2
  | 
        
        
            | 
            | 
           1136 | 
               if (position >= 0)
  | 
        
        
            | 
            | 
           1137 | 
               {
  | 
        
        
            | 
            | 
           1138 | 
                 unsigned i;
  | 
        
        
            | 
            | 
           1139 | 
                 printf("\n pos = %4X", position);
  | 
        
        
            | 
            | 
           1140 | 
                 for (i = cur; i <= lenEnd; i++)
  | 
        
        
            | 
            | 
           1141 | 
                 printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price);
  | 
        
        
            | 
            | 
           1142 | 
               }
  | 
        
        
            | 
            | 
           1143 | 
               #endif
  | 
        
        
            | 
            | 
           1144 | 
              | 
        
        
            | 
            | 
           1145 | 
             for (;;)
  | 
        
        
            | 
            | 
           1146 | 
             {
  | 
        
        
            | 
            | 
           1147 | 
               UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen;
  | 
        
        
            | 
            | 
           1148 | 
               UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice;
  | 
        
        
            | 
            | 
           1149 | 
               Bool nextIsChar;
  | 
        
        
            | 
            | 
           1150 | 
               Byte curByte, matchByte;
  | 
        
        
            | 
            | 
           1151 | 
               const Byte *data;
  | 
        
        
            | 
            | 
           1152 | 
               COptimal *curOpt;
  | 
        
        
            | 
            | 
           1153 | 
               COptimal *nextOpt;
  | 
        
        
            | 
            | 
           1154 | 
              | 
        
        
            | 
            | 
           1155 | 
               cur++;
  | 
        
        
            | 
            | 
           1156 | 
               if (cur == lenEnd)
  | 
        
        
            | 
            | 
           1157 | 
                 return Backward(p, backRes, cur);
  | 
        
        
            | 
            | 
           1158 | 
              | 
        
        
            | 
            | 
           1159 | 
               newLen = ReadMatchDistances(p, &numPairs);
  | 
        
        
            | 
            | 
           1160 | 
               if (newLen >= p->numFastBytes)
  | 
        
        
            | 
            | 
           1161 | 
               {
  | 
        
        
            | 
            | 
           1162 | 
                 p->numPairs = numPairs;
  | 
        
        
            | 
            | 
           1163 | 
                 p->longestMatchLength = newLen;
  | 
        
        
            | 
            | 
           1164 | 
                 return Backward(p, backRes, cur);
  | 
        
        
            | 
            | 
           1165 | 
               }
  | 
        
        
            | 
            | 
           1166 | 
               position++;
  | 
        
        
            | 
            | 
           1167 | 
               curOpt = &p->opt[cur];
  | 
        
        
            | 
            | 
           1168 | 
               posPrev = curOpt->posPrev;
  | 
        
        
            | 
            | 
           1169 | 
               if (curOpt->prev1IsChar)
  | 
        
        
            | 
            | 
           1170 | 
               {
  | 
        
        
            | 
            | 
           1171 | 
                 posPrev--;
  | 
        
        
            | 
            | 
           1172 | 
                 if (curOpt->prev2)
  | 
        
        
            | 
            | 
           1173 | 
                 {
  | 
        
        
            | 
            | 
           1174 | 
                   state = p->opt[curOpt->posPrev2].state;
  | 
        
        
            | 
            | 
           1175 | 
                   if (curOpt->backPrev2 < LZMA_NUM_REPS)
  | 
        
        
            | 
            | 
           1176 | 
                     state = kRepNextStates[state];
  | 
        
        
            | 
            | 
           1177 | 
                   else
  | 
        
        
            | 
            | 
           1178 | 
                     state = kMatchNextStates[state];
  | 
        
        
            | 
            | 
           1179 | 
                 }
  | 
        
        
            | 
            | 
           1180 | 
                 else
  | 
        
        
            | 
            | 
           1181 | 
                   state = p->opt[posPrev].state;
  | 
        
        
            | 
            | 
           1182 | 
                 state = kLiteralNextStates[state];
  | 
        
        
            | 
            | 
           1183 | 
               }
  | 
        
        
            | 
            | 
           1184 | 
               else
  | 
        
        
            | 
            | 
           1185 | 
                 state = p->opt[posPrev].state;
  | 
        
        
            | 
            | 
           1186 | 
               if (posPrev == cur - 1)
  | 
        
        
            | 
            | 
           1187 | 
               {
  | 
        
        
            | 
            | 
           1188 | 
                 if (IsShortRep(curOpt))
  | 
        
        
            | 
            | 
           1189 | 
                   state = kShortRepNextStates[state];
  | 
        
        
            | 
            | 
           1190 | 
                 else
  | 
        
        
            | 
            | 
           1191 | 
                   state = kLiteralNextStates[state];
  | 
        
        
            | 
            | 
           1192 | 
               }
  | 
        
        
            | 
            | 
           1193 | 
               else
  | 
        
        
            | 
            | 
           1194 | 
               {
  | 
        
        
            | 
            | 
           1195 | 
                 UInt32 pos;
  | 
        
        
            | 
            | 
           1196 | 
                 const COptimal *prevOpt;
  | 
        
        
            | 
            | 
           1197 | 
                 if (curOpt->prev1IsChar && curOpt->prev2)
  | 
        
        
            | 
            | 
           1198 | 
                 {
  | 
        
        
            | 
            | 
           1199 | 
                   posPrev = curOpt->posPrev2;
  | 
        
        
            | 
            | 
           1200 | 
                   pos = curOpt->backPrev2;
  | 
        
        
            | 
            | 
           1201 | 
                   state = kRepNextStates[state];
  | 
        
        
            | 
            | 
           1202 | 
                 }
  | 
        
        
            | 
            | 
           1203 | 
                 else
  | 
        
        
            | 
            | 
           1204 | 
                 {
  | 
        
        
            | 
            | 
           1205 | 
                   pos = curOpt->backPrev;
  | 
        
        
            | 
            | 
           1206 | 
                   if (pos < LZMA_NUM_REPS)
  | 
        
        
            | 
            | 
           1207 | 
                     state = kRepNextStates[state];
  | 
        
        
            | 
            | 
           1208 | 
                   else
  | 
        
        
            | 
            | 
           1209 | 
                     state = kMatchNextStates[state];
  | 
        
        
            | 
            | 
           1210 | 
                 }
  | 
        
        
            | 
            | 
           1211 | 
                 prevOpt = &p->opt[posPrev];
  | 
        
        
            | 
            | 
           1212 | 
                 if (pos < LZMA_NUM_REPS)
  | 
        
        
            | 
            | 
           1213 | 
                 {
  | 
        
        
            | 
            | 
           1214 | 
                   UInt32 i;
  | 
        
        
            | 
            | 
           1215 | 
                   reps[0] = prevOpt->backs[pos];
  | 
        
        
            | 
            | 
           1216 | 
                   for (i = 1; i <= pos; i++)
  | 
        
        
            | 
            | 
           1217 | 
                     reps[i] = prevOpt->backs[i - 1];
  | 
        
        
            | 
            | 
           1218 | 
                   for (; i < LZMA_NUM_REPS; i++)
  | 
        
        
            | 
            | 
           1219 | 
                     reps[i] = prevOpt->backs[i];
  | 
        
        
            | 
            | 
           1220 | 
                 }
  | 
        
        
            | 
            | 
           1221 | 
                 else
  | 
        
        
            | 
            | 
           1222 | 
                 {
  | 
        
        
            | 
            | 
           1223 | 
                   UInt32 i;
  | 
        
        
            | 
            | 
           1224 | 
                   reps[0] = (pos - LZMA_NUM_REPS);
  | 
        
        
            | 
            | 
           1225 | 
                   for (i = 1; i < LZMA_NUM_REPS; i++)
  | 
        
        
            | 
            | 
           1226 | 
                     reps[i] = prevOpt->backs[i - 1];
  | 
        
        
            | 
            | 
           1227 | 
                 }
  | 
        
        
            | 
            | 
           1228 | 
               }
  | 
        
        
            | 
            | 
           1229 | 
               curOpt->state = (CState)state;
  | 
        
        
            | 
            | 
           1230 | 
              | 
        
        
            | 
            | 
           1231 | 
               curOpt->backs[0] = reps[0];
  | 
        
        
            | 
            | 
           1232 | 
               curOpt->backs[1] = reps[1];
  | 
        
        
            | 
            | 
           1233 | 
               curOpt->backs[2] = reps[2];
  | 
        
        
            | 
            | 
           1234 | 
               curOpt->backs[3] = reps[3];
  | 
        
        
            | 
            | 
           1235 | 
              | 
        
        
            | 
            | 
           1236 | 
               curPrice = curOpt->price;
  | 
        
        
            | 
            | 
           1237 | 
               nextIsChar = False;
  | 
        
        
            | 
            | 
           1238 | 
               data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
  | 
        
        
            | 
            | 
           1239 | 
               curByte = *data;
  | 
        
        
            | 
            | 
           1240 | 
               matchByte = *(data - (reps[0] + 1));
  | 
        
        
            | 
            | 
           1241 | 
              | 
        
        
            | 
            | 
           1242 | 
               posState = (position & p->pbMask);
  | 
        
        
            | 
            | 
           1243 | 
              | 
        
        
            | 
            | 
           1244 | 
               curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]);
  | 
        
        
            | 
            | 
           1245 | 
               {
  | 
        
        
            | 
            | 
           1246 | 
                 const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
  | 
        
        
            | 
            | 
           1247 | 
                 curAnd1Price +=
  | 
        
        
            | 
            | 
           1248 | 
                   (!IsCharState(state) ?
  | 
        
        
            | 
            | 
           1249 | 
                     LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
  | 
        
        
            | 
            | 
           1250 | 
                     LitEnc_GetPrice(probs, curByte, p->ProbPrices));
  | 
        
        
            | 
            | 
           1251 | 
               }
  | 
        
        
            | 
            | 
           1252 | 
              | 
        
        
            | 
            | 
           1253 | 
               nextOpt = &p->opt[cur + 1];
  | 
        
        
            | 
            | 
           1254 | 
              | 
        
        
            | 
            | 
           1255 | 
               if (curAnd1Price < nextOpt->price)
  | 
        
        
            | 
            | 
           1256 | 
               {
  | 
        
        
            | 
            | 
           1257 | 
                 nextOpt->price = curAnd1Price;
  | 
        
        
            | 
            | 
           1258 | 
                 nextOpt->posPrev = cur;
  | 
        
        
            | 
            | 
           1259 | 
                 MakeAsChar(nextOpt);
  | 
        
        
            | 
            | 
           1260 | 
                 nextIsChar = True;
  | 
        
        
            | 
            | 
           1261 | 
               }
  | 
        
        
            | 
            | 
           1262 | 
              | 
        
        
            | 
            | 
           1263 | 
               matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]);
  | 
        
        
            | 
            | 
           1264 | 
               repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]);
  | 
        
        
            | 
            | 
           1265 | 
              | 
        
        
            | 
            | 
           1266 | 
               if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0))
  | 
        
        
            | 
            | 
           1267 | 
               {
  | 
        
        
            | 
            | 
           1268 | 
                 UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState);
  | 
        
        
            | 
            | 
           1269 | 
                 if (shortRepPrice <= nextOpt->price)
  | 
        
        
            | 
            | 
           1270 | 
                 {
  | 
        
        
            | 
            | 
           1271 | 
                   nextOpt->price = shortRepPrice;
  | 
        
        
            | 
            | 
           1272 | 
                   nextOpt->posPrev = cur;
  | 
        
        
            | 
            | 
           1273 | 
                   MakeAsShortRep(nextOpt);
  | 
        
        
            | 
            | 
           1274 | 
                   nextIsChar = True;
  | 
        
        
            | 
            | 
           1275 | 
                 }
  | 
        
        
            | 
            | 
           1276 | 
               }
  | 
        
        
            | 
            | 
           1277 | 
               numAvailFull = p->numAvail;
  | 
        
        
            | 
            | 
           1278 | 
               {
  | 
        
        
            | 
            | 
           1279 | 
                 UInt32 temp = kNumOpts - 1 - cur;
  | 
        
        
            | 
            | 
           1280 | 
                 if (temp < numAvailFull)
  | 
        
        
            | 
            | 
           1281 | 
                   numAvailFull = temp;
  | 
        
        
            | 
            | 
           1282 | 
               }
  | 
        
        
            | 
            | 
           1283 | 
              | 
        
        
            | 
            | 
           1284 | 
               if (numAvailFull < 2)
  | 
        
        
            | 
            | 
           1285 | 
                 continue;
  | 
        
        
            | 
            | 
           1286 | 
               numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes);
  | 
        
        
            | 
            | 
           1287 | 
              | 
        
        
            | 
            | 
           1288 | 
               if (!nextIsChar && matchByte != curByte) /* speed optimization */
  | 
        
        
            | 
            | 
           1289 | 
               {
  | 
        
        
            | 
            | 
           1290 | 
                 /* try Literal + rep0 */
  | 
        
        
            | 
            | 
           1291 | 
                 UInt32 temp;
  | 
        
        
            | 
            | 
           1292 | 
                 UInt32 lenTest2;
  | 
        
        
            | 
            | 
           1293 | 
                 const Byte *data2 = data - (reps[0] + 1);
  | 
        
        
            | 
            | 
           1294 | 
                 UInt32 limit = p->numFastBytes + 1;
  | 
        
        
            | 
            | 
           1295 | 
                 if (limit > numAvailFull)
  | 
        
        
            | 
            | 
           1296 | 
                   limit = numAvailFull;
  | 
        
        
            | 
            | 
           1297 | 
              | 
        
        
            | 
            | 
           1298 | 
                 for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++);
  | 
        
        
            | 
            | 
           1299 | 
                 lenTest2 = temp - 1;
  | 
        
        
            | 
            | 
           1300 | 
                 if (lenTest2 >= 2)
  | 
        
        
            | 
            | 
           1301 | 
                 {
  | 
        
        
            | 
            | 
           1302 | 
                   UInt32 state2 = kLiteralNextStates[state];
  | 
        
        
            | 
            | 
           1303 | 
                   UInt32 posStateNext = (position + 1) & p->pbMask;
  | 
        
        
            | 
            | 
           1304 | 
                   UInt32 nextRepMatchPrice = curAnd1Price +
  | 
        
        
            | 
            | 
           1305 | 
                       GET_PRICE_1(p->isMatch[state2][posStateNext]) +
  | 
        
        
            | 
            | 
           1306 | 
                       GET_PRICE_1(p->isRep[state2]);
  | 
        
        
            | 
            | 
           1307 | 
                   /* for (; lenTest2 >= 2; lenTest2--) */
  | 
        
        
            | 
            | 
           1308 | 
                   {
  | 
        
        
            | 
            | 
           1309 | 
                     UInt32 curAndLenPrice;
  | 
        
        
            | 
            | 
           1310 | 
                     COptimal *opt;
  | 
        
        
            | 
            | 
           1311 | 
                     UInt32 offset = cur + 1 + lenTest2;
  | 
        
        
            | 
            | 
           1312 | 
                     while (lenEnd < offset)
  | 
        
        
            | 
            | 
           1313 | 
                       p->opt[++lenEnd].price = kInfinityPrice;
  | 
        
        
            | 
            | 
           1314 | 
                     curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
  | 
        
        
            | 
            | 
           1315 | 
                     opt = &p->opt[offset];
  | 
        
        
            | 
            | 
           1316 | 
                     if (curAndLenPrice < opt->price)
  | 
        
        
            | 
            | 
           1317 | 
                     {
  | 
        
        
            | 
            | 
           1318 | 
                       opt->price = curAndLenPrice;
  | 
        
        
            | 
            | 
           1319 | 
                       opt->posPrev = cur + 1;
  | 
        
        
            | 
            | 
           1320 | 
                       opt->backPrev = 0;
  | 
        
        
            | 
            | 
           1321 | 
                       opt->prev1IsChar = True;
  | 
        
        
            | 
            | 
           1322 | 
                       opt->prev2 = False;
  | 
        
        
            | 
            | 
           1323 | 
                     }
  | 
        
        
            | 
            | 
           1324 | 
                   }
  | 
        
        
            | 
            | 
           1325 | 
                 }
  | 
        
        
            | 
            | 
           1326 | 
               }
  | 
        
        
            | 
            | 
           1327 | 
              | 
        
        
            | 
            | 
           1328 | 
               startLen = 2; /* speed optimization */
  | 
        
        
            | 
            | 
           1329 | 
               {
  | 
        
        
            | 
            | 
           1330 | 
               UInt32 repIndex;
  | 
        
        
            | 
            | 
           1331 | 
               for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++)
  | 
        
        
            | 
            | 
           1332 | 
               {
  | 
        
        
            | 
            | 
           1333 | 
                 UInt32 lenTest;
  | 
        
        
            | 
            | 
           1334 | 
                 UInt32 lenTestTemp;
  | 
        
        
            | 
            | 
           1335 | 
                 UInt32 price;
  | 
        
        
            | 
            | 
           1336 | 
                 const Byte *data2 = data - (reps[repIndex] + 1);
  | 
        
        
            | 
            | 
           1337 | 
                 if (data[0] != data2[0] || data[1] != data2[1])
  | 
        
        
            | 
            | 
           1338 | 
                   continue;
  | 
        
        
            | 
            | 
           1339 | 
                 for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
  | 
        
        
            | 
            | 
           1340 | 
                 while (lenEnd < cur + lenTest)
  | 
        
        
            | 
            | 
           1341 | 
                   p->opt[++lenEnd].price = kInfinityPrice;
  | 
        
        
            | 
            | 
           1342 | 
                 lenTestTemp = lenTest;
  | 
        
        
            | 
            | 
           1343 | 
                 price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState);
  | 
        
        
            | 
            | 
           1344 | 
                 do
  | 
        
        
            | 
            | 
           1345 | 
                 {
  | 
        
        
            | 
            | 
           1346 | 
                   UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2];
  | 
        
        
            | 
            | 
           1347 | 
                   COptimal *opt = &p->opt[cur + lenTest];
  | 
        
        
            | 
            | 
           1348 | 
                   if (curAndLenPrice < opt->price)
  | 
        
        
            | 
            | 
           1349 | 
                   {
  | 
        
        
            | 
            | 
           1350 | 
                     opt->price = curAndLenPrice;
  | 
        
        
            | 
            | 
           1351 | 
                     opt->posPrev = cur;
  | 
        
        
            | 
            | 
           1352 | 
                     opt->backPrev = repIndex;
  | 
        
        
            | 
            | 
           1353 | 
                     opt->prev1IsChar = False;
  | 
        
        
            | 
            | 
           1354 | 
                   }
  | 
        
        
            | 
            | 
           1355 | 
                 }
  | 
        
        
            | 
            | 
           1356 | 
                 while (--lenTest >= 2);
  | 
        
        
            | 
            | 
           1357 | 
                 lenTest = lenTestTemp;
  | 
        
        
            | 
            | 
           1358 | 
              | 
        
        
            | 
            | 
           1359 | 
                 if (repIndex == 0)
  | 
        
        
            | 
            | 
           1360 | 
                   startLen = lenTest + 1;
  | 
        
        
            | 
            | 
           1361 | 
              | 
        
        
            | 
            | 
           1362 | 
                 /* if (_maxMode) */
  | 
        
        
            | 
            | 
           1363 | 
                   {
  | 
        
        
            | 
            | 
           1364 | 
                     UInt32 lenTest2 = lenTest + 1;
  | 
        
        
            | 
            | 
           1365 | 
                     UInt32 limit = lenTest2 + p->numFastBytes;
  | 
        
        
            | 
            | 
           1366 | 
                     UInt32 nextRepMatchPrice;
  | 
        
        
            | 
            | 
           1367 | 
                     if (limit > numAvailFull)
  | 
        
        
            | 
            | 
           1368 | 
                       limit = numAvailFull;
  | 
        
        
            | 
            | 
           1369 | 
                     for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
  | 
        
        
            | 
            | 
           1370 | 
                     lenTest2 -= lenTest + 1;
  | 
        
        
            | 
            | 
           1371 | 
                     if (lenTest2 >= 2)
  | 
        
        
            | 
            | 
           1372 | 
                     {
  | 
        
        
            | 
            | 
           1373 | 
                       UInt32 state2 = kRepNextStates[state];
  | 
        
        
            | 
            | 
           1374 | 
                       UInt32 posStateNext = (position + lenTest) & p->pbMask;
  | 
        
        
            | 
            | 
           1375 | 
                       UInt32 curAndLenCharPrice =
  | 
        
        
            | 
            | 
           1376 | 
                           price + p->repLenEnc.prices[posState][lenTest - 2] +
  | 
        
        
            | 
            | 
           1377 | 
                           GET_PRICE_0(p->isMatch[state2][posStateNext]) +
  | 
        
        
            | 
            | 
           1378 | 
                           LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
  | 
        
        
            | 
            | 
           1379 | 
                               data[lenTest], data2[lenTest], p->ProbPrices);
  | 
        
        
            | 
            | 
           1380 | 
                       state2 = kLiteralNextStates[state2];
  | 
        
        
            | 
            | 
           1381 | 
                       posStateNext = (position + lenTest + 1) & p->pbMask;
  | 
        
        
            | 
            | 
           1382 | 
                       nextRepMatchPrice = curAndLenCharPrice +
  | 
        
        
            | 
            | 
           1383 | 
                           GET_PRICE_1(p->isMatch[state2][posStateNext]) +
  | 
        
        
            | 
            | 
           1384 | 
                           GET_PRICE_1(p->isRep[state2]);
  | 
        
        
            | 
            | 
           1385 | 
              | 
        
        
            | 
            | 
           1386 | 
                       /* for (; lenTest2 >= 2; lenTest2--) */
  | 
        
        
            | 
            | 
           1387 | 
                       {
  | 
        
        
            | 
            | 
           1388 | 
                         UInt32 curAndLenPrice;
  | 
        
        
            | 
            | 
           1389 | 
                         COptimal *opt;
  | 
        
        
            | 
            | 
           1390 | 
                         UInt32 offset = cur + lenTest + 1 + lenTest2;
  | 
        
        
            | 
            | 
           1391 | 
                         while (lenEnd < offset)
  | 
        
        
            | 
            | 
           1392 | 
                           p->opt[++lenEnd].price = kInfinityPrice;
  | 
        
        
            | 
            | 
           1393 | 
                         curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
  | 
        
        
            | 
            | 
           1394 | 
                         opt = &p->opt[offset];
  | 
        
        
            | 
            | 
           1395 | 
                         if (curAndLenPrice < opt->price)
  | 
        
        
            | 
            | 
           1396 | 
                         {
  | 
        
        
            | 
            | 
           1397 | 
                           opt->price = curAndLenPrice;
  | 
        
        
            | 
            | 
           1398 | 
                           opt->posPrev = cur + lenTest + 1;
  | 
        
        
            | 
            | 
           1399 | 
                           opt->backPrev = 0;
  | 
        
        
            | 
            | 
           1400 | 
                           opt->prev1IsChar = True;
  | 
        
        
            | 
            | 
           1401 | 
                           opt->prev2 = True;
  | 
        
        
            | 
            | 
           1402 | 
                           opt->posPrev2 = cur;
  | 
        
        
            | 
            | 
           1403 | 
                           opt->backPrev2 = repIndex;
  | 
        
        
            | 
            | 
           1404 | 
                         }
  | 
        
        
            | 
            | 
           1405 | 
                       }
  | 
        
        
            | 
            | 
           1406 | 
                     }
  | 
        
        
            | 
            | 
           1407 | 
                   }
  | 
        
        
            | 
            | 
           1408 | 
               }
  | 
        
        
            | 
            | 
           1409 | 
               }
  | 
        
        
            | 
            | 
           1410 | 
               /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */
  | 
        
        
            | 
            | 
           1411 | 
               if (newLen > numAvail)
  | 
        
        
            | 
            | 
           1412 | 
               {
  | 
        
        
            | 
            | 
           1413 | 
                 newLen = numAvail;
  | 
        
        
            | 
            | 
           1414 | 
                 for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2);
  | 
        
        
            | 
            | 
           1415 | 
                 matches[numPairs] = newLen;
  | 
        
        
            | 
            | 
           1416 | 
                 numPairs += 2;
  | 
        
        
            | 
            | 
           1417 | 
               }
  | 
        
        
            | 
            | 
           1418 | 
               if (newLen >= startLen)
  | 
        
        
            | 
            | 
           1419 | 
               {
  | 
        
        
            | 
            | 
           1420 | 
                 UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]);
  | 
        
        
            | 
            | 
           1421 | 
                 UInt32 offs, curBack, posSlot;
  | 
        
        
            | 
            | 
           1422 | 
                 UInt32 lenTest;
  | 
        
        
            | 
            | 
           1423 | 
                 while (lenEnd < cur + newLen)
  | 
        
        
            | 
            | 
           1424 | 
                   p->opt[++lenEnd].price = kInfinityPrice;
  | 
        
        
            | 
            | 
           1425 | 
              | 
        
        
            | 
            | 
           1426 | 
                 offs = 0;
  | 
        
        
            | 
            | 
           1427 | 
                 while (startLen > matches[offs])
  | 
        
        
            | 
            | 
           1428 | 
                   offs += 2;
  | 
        
        
            | 
            | 
           1429 | 
                 curBack = matches[offs + 1];
  | 
        
        
            | 
            | 
           1430 | 
                 GetPosSlot2(curBack, posSlot);
  | 
        
        
            | 
            | 
           1431 | 
                 for (lenTest = /*2*/ startLen; ; lenTest++)
  | 
        
        
            | 
            | 
           1432 | 
                 {
  | 
        
        
            | 
            | 
           1433 | 
                   UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN];
  | 
        
        
            | 
            | 
           1434 | 
                   UInt32 lenToPosState = GetLenToPosState(lenTest);
  | 
        
        
            | 
            | 
           1435 | 
                   COptimal *opt;
  | 
        
        
            | 
            | 
           1436 | 
                   if (curBack < kNumFullDistances)
  | 
        
        
            | 
            | 
           1437 | 
                     curAndLenPrice += p->distancesPrices[lenToPosState][curBack];
  | 
        
        
            | 
            | 
           1438 | 
                   else
  | 
        
        
            | 
            | 
           1439 | 
                     curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask];
  | 
        
        
            | 
            | 
           1440 | 
              | 
        
        
            | 
            | 
           1441 | 
                   opt = &p->opt[cur + lenTest];
  | 
        
        
            | 
            | 
           1442 | 
                   if (curAndLenPrice < opt->price)
  | 
        
        
            | 
            | 
           1443 | 
                   {
  | 
        
        
            | 
            | 
           1444 | 
                     opt->price = curAndLenPrice;
  | 
        
        
            | 
            | 
           1445 | 
                     opt->posPrev = cur;
  | 
        
        
            | 
            | 
           1446 | 
                     opt->backPrev = curBack + LZMA_NUM_REPS;
  | 
        
        
            | 
            | 
           1447 | 
                     opt->prev1IsChar = False;
  | 
        
        
            | 
            | 
           1448 | 
                   }
  | 
        
        
            | 
            | 
           1449 | 
              | 
        
        
            | 
            | 
           1450 | 
                   if (/*_maxMode && */lenTest == matches[offs])
  | 
        
        
            | 
            | 
           1451 | 
                   {
  | 
        
        
            | 
            | 
           1452 | 
                     /* Try Match + Literal + Rep0 */
  | 
        
        
            | 
            | 
           1453 | 
                     const Byte *data2 = data - (curBack + 1);
  | 
        
        
            | 
            | 
           1454 | 
                     UInt32 lenTest2 = lenTest + 1;
  | 
        
        
            | 
            | 
           1455 | 
                     UInt32 limit = lenTest2 + p->numFastBytes;
  | 
        
        
            | 
            | 
           1456 | 
                     UInt32 nextRepMatchPrice;
  | 
        
        
            | 
            | 
           1457 | 
                     if (limit > numAvailFull)
  | 
        
        
            | 
            | 
           1458 | 
                       limit = numAvailFull;
  | 
        
        
            | 
            | 
           1459 | 
                     for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
  | 
        
        
            | 
            | 
           1460 | 
                     lenTest2 -= lenTest + 1;
  | 
        
        
            | 
            | 
           1461 | 
                     if (lenTest2 >= 2)
  | 
        
        
            | 
            | 
           1462 | 
                     {
  | 
        
        
            | 
            | 
           1463 | 
                       UInt32 state2 = kMatchNextStates[state];
  | 
        
        
            | 
            | 
           1464 | 
                       UInt32 posStateNext = (position + lenTest) & p->pbMask;
  | 
        
        
            | 
            | 
           1465 | 
                       UInt32 curAndLenCharPrice = curAndLenPrice +
  | 
        
        
            | 
            | 
           1466 | 
                           GET_PRICE_0(p->isMatch[state2][posStateNext]) +
  | 
        
        
            | 
            | 
           1467 | 
                           LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
  | 
        
        
            | 
            | 
           1468 | 
                               data[lenTest], data2[lenTest], p->ProbPrices);
  | 
        
        
            | 
            | 
           1469 | 
                       state2 = kLiteralNextStates[state2];
  | 
        
        
            | 
            | 
           1470 | 
                       posStateNext = (posStateNext + 1) & p->pbMask;
  | 
        
        
            | 
            | 
           1471 | 
                       nextRepMatchPrice = curAndLenCharPrice +
  | 
        
        
            | 
            | 
           1472 | 
                           GET_PRICE_1(p->isMatch[state2][posStateNext]) +
  | 
        
        
            | 
            | 
           1473 | 
                           GET_PRICE_1(p->isRep[state2]);
  | 
        
        
            | 
            | 
           1474 | 
              | 
        
        
            | 
            | 
           1475 | 
                       /* for (; lenTest2 >= 2; lenTest2--) */
  | 
        
        
            | 
            | 
           1476 | 
                       {
  | 
        
        
            | 
            | 
           1477 | 
                         UInt32 offset = cur + lenTest + 1 + lenTest2;
  | 
        
        
            | 
            | 
           1478 | 
                         UInt32 curAndLenPrice;
  | 
        
        
            | 
            | 
           1479 | 
                         COptimal *opt;
  | 
        
        
            | 
            | 
           1480 | 
                         while (lenEnd < offset)
  | 
        
        
            | 
            | 
           1481 | 
                           p->opt[++lenEnd].price = kInfinityPrice;
  | 
        
        
            | 
            | 
           1482 | 
                         curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
  | 
        
        
            | 
            | 
           1483 | 
                         opt = &p->opt[offset];
  | 
        
        
            | 
            | 
           1484 | 
                         if (curAndLenPrice < opt->price)
  | 
        
        
            | 
            | 
           1485 | 
                         {
  | 
        
        
            | 
            | 
           1486 | 
                           opt->price = curAndLenPrice;
  | 
        
        
            | 
            | 
           1487 | 
                           opt->posPrev = cur + lenTest + 1;
  | 
        
        
            | 
            | 
           1488 | 
                           opt->backPrev = 0;
  | 
        
        
            | 
            | 
           1489 | 
                           opt->prev1IsChar = True;
  | 
        
        
            | 
            | 
           1490 | 
                           opt->prev2 = True;
  | 
        
        
            | 
            | 
           1491 | 
                           opt->posPrev2 = cur;
  | 
        
        
            | 
            | 
           1492 | 
                           opt->backPrev2 = curBack + LZMA_NUM_REPS;
  | 
        
        
            | 
            | 
           1493 | 
                         }
  | 
        
        
            | 
            | 
           1494 | 
                       }
  | 
        
        
            | 
            | 
           1495 | 
                     }
  | 
        
        
            | 
            | 
           1496 | 
                     offs += 2;
  | 
        
        
            | 
            | 
           1497 | 
                     if (offs == numPairs)
  | 
        
        
            | 
            | 
           1498 | 
                       break;
  | 
        
        
            | 
            | 
           1499 | 
                     curBack = matches[offs + 1];
  | 
        
        
            | 
            | 
           1500 | 
                     if (curBack >= kNumFullDistances)
  | 
        
        
            | 
            | 
           1501 | 
                       GetPosSlot2(curBack, posSlot);
  | 
        
        
            | 
            | 
           1502 | 
                   }
  | 
        
        
            | 
            | 
           1503 | 
                 }
  | 
        
        
            | 
            | 
           1504 | 
               }
  | 
        
        
            | 
            | 
           1505 | 
             }
  | 
        
        
            | 
            | 
           1506 | 
           }
  | 
        
        
            | 
            | 
           1507 | 
              | 
        
        
            | 
            | 
           1508 | 
           #define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist))
  | 
        
        
            | 
            | 
           1509 | 
              | 
        
        
            | 
            | 
           1510 | 
           static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
  | 
        
        
            | 
            | 
           1511 | 
           {
  | 
        
        
            | 
            | 
           1512 | 
             UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i;
  | 
        
        
            | 
            | 
           1513 | 
             const Byte *data;
  | 
        
        
            | 
            | 
           1514 | 
             const UInt32 *matches;
  | 
        
        
            | 
            | 
           1515 | 
              | 
        
        
            | 
            | 
           1516 | 
             if (p->additionalOffset == 0)
  | 
        
        
            | 
            | 
           1517 | 
               mainLen = ReadMatchDistances(p, &numPairs);
  | 
        
        
            | 
            | 
           1518 | 
             else
  | 
        
        
            | 
            | 
           1519 | 
             {
  | 
        
        
            | 
            | 
           1520 | 
               mainLen = p->longestMatchLength;
  | 
        
        
            | 
            | 
           1521 | 
               numPairs = p->numPairs;
  | 
        
        
            | 
            | 
           1522 | 
             }
  | 
        
        
            | 
            | 
           1523 | 
              | 
        
        
            | 
            | 
           1524 | 
             numAvail = p->numAvail;
  | 
        
        
            | 
            | 
           1525 | 
             *backRes = (UInt32)-1;
  | 
        
        
            | 
            | 
           1526 | 
             if (numAvail < 2)
  | 
        
        
            | 
            | 
           1527 | 
               return 1;
  | 
        
        
            | 
            | 
           1528 | 
             if (numAvail > LZMA_MATCH_LEN_MAX)
  | 
        
        
            | 
            | 
           1529 | 
               numAvail = LZMA_MATCH_LEN_MAX;
  | 
        
        
            | 
            | 
           1530 | 
             data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
  | 
        
        
            | 
            | 
           1531 | 
              | 
        
        
            | 
            | 
           1532 | 
             repLen = repIndex = 0;
  | 
        
        
            | 
            | 
           1533 | 
             for (i = 0; i < LZMA_NUM_REPS; i++)
  | 
        
        
            | 
            | 
           1534 | 
             {
  | 
        
        
            | 
            | 
           1535 | 
               UInt32 len;
  | 
        
        
            | 
            | 
           1536 | 
               const Byte *data2 = data - (p->reps[i] + 1);
  | 
        
        
            | 
            | 
           1537 | 
               if (data[0] != data2[0] || data[1] != data2[1])
  | 
        
        
            | 
            | 
           1538 | 
                 continue;
  | 
        
        
            | 
            | 
           1539 | 
               for (len = 2; len < numAvail && data[len] == data2[len]; len++);
  | 
        
        
            | 
            | 
           1540 | 
               if (len >= p->numFastBytes)
  | 
        
        
            | 
            | 
           1541 | 
               {
  | 
        
        
            | 
            | 
           1542 | 
                 *backRes = i;
  | 
        
        
            | 
            | 
           1543 | 
                 MovePos(p, len - 1);
  | 
        
        
            | 
            | 
           1544 | 
                 return len;
  | 
        
        
            | 
            | 
           1545 | 
               }
  | 
        
        
            | 
            | 
           1546 | 
               if (len > repLen)
  | 
        
        
            | 
            | 
           1547 | 
               {
  | 
        
        
            | 
            | 
           1548 | 
                 repIndex = i;
  | 
        
        
            | 
            | 
           1549 | 
                 repLen = len;
  | 
        
        
            | 
            | 
           1550 | 
               }
  | 
        
        
            | 
            | 
           1551 | 
             }
  | 
        
        
            | 
            | 
           1552 | 
              | 
        
        
            | 
            | 
           1553 | 
             matches = p->matches;
  | 
        
        
            | 
            | 
           1554 | 
             if (mainLen >= p->numFastBytes)
  | 
        
        
            | 
            | 
           1555 | 
             {
  | 
        
        
            | 
            | 
           1556 | 
               *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
  | 
        
        
            | 
            | 
           1557 | 
               MovePos(p, mainLen - 1);
  | 
        
        
            | 
            | 
           1558 | 
               return mainLen;
  | 
        
        
            | 
            | 
           1559 | 
             }
  | 
        
        
            | 
            | 
           1560 | 
              | 
        
        
            | 
            | 
           1561 | 
             mainDist = 0; /* for GCC */
  | 
        
        
            | 
            | 
           1562 | 
             if (mainLen >= 2)
  | 
        
        
            | 
            | 
           1563 | 
             {
  | 
        
        
            | 
            | 
           1564 | 
               mainDist = matches[numPairs - 1];
  | 
        
        
            | 
            | 
           1565 | 
               while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1)
  | 
        
        
            | 
            | 
           1566 | 
               {
  | 
        
        
            | 
            | 
           1567 | 
                 if (!ChangePair(matches[numPairs - 3], mainDist))
  | 
        
        
            | 
            | 
           1568 | 
                   break;
  | 
        
        
            | 
            | 
           1569 | 
                 numPairs -= 2;
  | 
        
        
            | 
            | 
           1570 | 
                 mainLen = matches[numPairs - 2];
  | 
        
        
            | 
            | 
           1571 | 
                 mainDist = matches[numPairs - 1];
  | 
        
        
            | 
            | 
           1572 | 
               }
  | 
        
        
            | 
            | 
           1573 | 
               if (mainLen == 2 && mainDist >= 0x80)
  | 
        
        
            | 
            | 
           1574 | 
                 mainLen = 1;
  | 
        
        
            | 
            | 
           1575 | 
             }
  | 
        
        
            | 
            | 
           1576 | 
              | 
        
        
            | 
            | 
           1577 | 
             if (repLen >= 2 && (
  | 
        
        
            | 
            | 
           1578 | 
                   (repLen + 1 >= mainLen) ||
  | 
        
        
            | 
            | 
           1579 | 
                   (repLen + 2 >= mainLen && mainDist >= (1 << 9)) ||
  | 
        
        
            | 
            | 
           1580 | 
                   (repLen + 3 >= mainLen && mainDist >= (1 << 15))))
  | 
        
        
            | 
            | 
           1581 | 
             {
  | 
        
        
            | 
            | 
           1582 | 
               *backRes = repIndex;
  | 
        
        
            | 
            | 
           1583 | 
               MovePos(p, repLen - 1);
  | 
        
        
            | 
            | 
           1584 | 
               return repLen;
  | 
        
        
            | 
            | 
           1585 | 
             }
  | 
        
        
            | 
            | 
           1586 | 
              | 
        
        
            | 
            | 
           1587 | 
             if (mainLen < 2 || numAvail <= 2)
  | 
        
        
            | 
            | 
           1588 | 
               return 1;
  | 
        
        
            | 
            | 
           1589 | 
              | 
        
        
            | 
            | 
           1590 | 
             p->longestMatchLength = ReadMatchDistances(p, &p->numPairs);
  | 
        
        
            | 
            | 
           1591 | 
             if (p->longestMatchLength >= 2)
  | 
        
        
            | 
            | 
           1592 | 
             {
  | 
        
        
            | 
            | 
           1593 | 
               UInt32 newDistance = matches[p->numPairs - 1];
  | 
        
        
            | 
            | 
           1594 | 
               if ((p->longestMatchLength >= mainLen && newDistance < mainDist) ||
  | 
        
        
            | 
            | 
           1595 | 
                   (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) ||
  | 
        
        
            | 
            | 
           1596 | 
                   (p->longestMatchLength > mainLen + 1) ||
  | 
        
        
            | 
            | 
           1597 | 
                   (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist)))
  | 
        
        
            | 
            | 
           1598 | 
                 return 1;
  | 
        
        
            | 
            | 
           1599 | 
             }
  | 
        
        
            | 
            | 
           1600 | 
              | 
        
        
            | 
            | 
           1601 | 
             data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
  | 
        
        
            | 
            | 
           1602 | 
             for (i = 0; i < LZMA_NUM_REPS; i++)
  | 
        
        
            | 
            | 
           1603 | 
             {
  | 
        
        
            | 
            | 
           1604 | 
               UInt32 len, limit;
  | 
        
        
            | 
            | 
           1605 | 
               const Byte *data2 = data - (p->reps[i] + 1);
  | 
        
        
            | 
            | 
           1606 | 
               if (data[0] != data2[0] || data[1] != data2[1])
  | 
        
        
            | 
            | 
           1607 | 
                 continue;
  | 
        
        
            | 
            | 
           1608 | 
               limit = mainLen - 1;
  | 
        
        
            | 
            | 
           1609 | 
               for (len = 2; len < limit && data[len] == data2[len]; len++);
  | 
        
        
            | 
            | 
           1610 | 
               if (len >= limit)
  | 
        
        
            | 
            | 
           1611 | 
                 return 1;
  | 
        
        
            | 
            | 
           1612 | 
             }
  | 
        
        
            | 
            | 
           1613 | 
             *backRes = mainDist + LZMA_NUM_REPS;
  | 
        
        
            | 
            | 
           1614 | 
             MovePos(p, mainLen - 2);
  | 
        
        
            | 
            | 
           1615 | 
             return mainLen;
  | 
        
        
            | 
            | 
           1616 | 
           }
  | 
        
        
            | 
            | 
           1617 | 
              | 
        
        
            | 
            | 
           1618 | 
           static void WriteEndMarker(CLzmaEnc *p, UInt32 posState)
  | 
        
        
            | 
            | 
           1619 | 
           {
  | 
        
        
            | 
            | 
           1620 | 
             UInt32 len;
  | 
        
        
            | 
            | 
           1621 | 
             RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
  | 
        
        
            | 
            | 
           1622 | 
             RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
  | 
        
        
            | 
            | 
           1623 | 
             p->state = kMatchNextStates[p->state];
  | 
        
        
            | 
            | 
           1624 | 
             len = LZMA_MATCH_LEN_MIN;
  | 
        
        
            | 
            | 
           1625 | 
             LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
  | 
        
        
            | 
            | 
           1626 | 
             RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1);
  | 
        
        
            | 
            | 
           1627 | 
             RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits);
  | 
        
        
            | 
            | 
           1628 | 
             RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);
  | 
        
        
            | 
            | 
           1629 | 
           }
  | 
        
        
            | 
            | 
           1630 | 
              | 
        
        
            | 
            | 
           1631 | 
           static SRes CheckErrors(CLzmaEnc *p)
  | 
        
        
            | 
            | 
           1632 | 
           {
  | 
        
        
            | 
            | 
           1633 | 
             if (p->result != SZ_OK)
  | 
        
        
            | 
            | 
           1634 | 
               return p->result;
  | 
        
        
            | 
            | 
           1635 | 
             if (p->rc.res != SZ_OK)
  | 
        
        
            | 
            | 
           1636 | 
               p->result = SZ_ERROR_WRITE;
  | 
        
        
            | 
            | 
           1637 | 
             if (p->matchFinderBase.result != SZ_OK)
  | 
        
        
            | 
            | 
           1638 | 
               p->result = SZ_ERROR_READ;
  | 
        
        
            | 
            | 
           1639 | 
             if (p->result != SZ_OK)
  | 
        
        
            | 
            | 
           1640 | 
               p->finished = True;
  | 
        
        
            | 
            | 
           1641 | 
             return p->result;
  | 
        
        
            | 
            | 
           1642 | 
           }
  | 
        
        
            | 
            | 
           1643 | 
              | 
        
        
            | 
            | 
           1644 | 
           static SRes Flush(CLzmaEnc *p, UInt32 nowPos)
  | 
        
        
            | 
            | 
           1645 | 
           {
  | 
        
        
            | 
            | 
           1646 | 
             /* ReleaseMFStream(); */
  | 
        
        
            | 
            | 
           1647 | 
             p->finished = True;
  | 
        
        
            | 
            | 
           1648 | 
             if (p->writeEndMark)
  | 
        
        
            | 
            | 
           1649 | 
               WriteEndMarker(p, nowPos & p->pbMask);
  | 
        
        
            | 
            | 
           1650 | 
             RangeEnc_FlushData(&p->rc);
  | 
        
        
            | 
            | 
           1651 | 
             RangeEnc_FlushStream(&p->rc);
  | 
        
        
            | 
            | 
           1652 | 
             return CheckErrors(p);
  | 
        
        
            | 
            | 
           1653 | 
           }
  | 
        
        
            | 
            | 
           1654 | 
              | 
        
        
            | 
            | 
           1655 | 
           static void FillAlignPrices(CLzmaEnc *p)
  | 
        
        
            | 
            | 
           1656 | 
           {
  | 
        
        
            | 
            | 
           1657 | 
             UInt32 i;
  | 
        
        
            | 
            | 
           1658 | 
             for (i = 0; i < kAlignTableSize; i++)
  | 
        
        
            | 
            | 
           1659 | 
               p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices);
  | 
        
        
            | 
            | 
           1660 | 
             p->alignPriceCount = 0;
  | 
        
        
            | 
            | 
           1661 | 
           }
  | 
        
        
            | 
            | 
           1662 | 
              | 
        
        
            | 
            | 
           1663 | 
           static void FillDistancesPrices(CLzmaEnc *p)
  | 
        
        
            | 
            | 
           1664 | 
           {
  | 
        
        
            | 
            | 
           1665 | 
             UInt32 tempPrices[kNumFullDistances];
  | 
        
        
            | 
            | 
           1666 | 
             UInt32 i, lenToPosState;
  | 
        
        
            | 
            | 
           1667 | 
             for (i = kStartPosModelIndex; i < kNumFullDistances; i++)
  | 
        
        
            | 
            | 
           1668 | 
             {
  | 
        
        
            | 
            | 
           1669 | 
               UInt32 posSlot = GetPosSlot1(i);
  | 
        
        
            | 
            | 
           1670 | 
               UInt32 footerBits = ((posSlot >> 1) - 1);
  | 
        
        
            | 
            | 
           1671 | 
               UInt32 base = ((2 | (posSlot & 1)) << footerBits);
  | 
        
        
            | 
            | 
           1672 | 
               tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices);
  | 
        
        
            | 
            | 
           1673 | 
             }
  | 
        
        
            | 
            | 
           1674 | 
              | 
        
        
            | 
            | 
           1675 | 
             for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
  | 
        
        
            | 
            | 
           1676 | 
             {
  | 
        
        
            | 
            | 
           1677 | 
               UInt32 posSlot;
  | 
        
        
            | 
            | 
           1678 | 
               const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState];
  | 
        
        
            | 
            | 
           1679 | 
               UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState];
  | 
        
        
            | 
            | 
           1680 | 
               for (posSlot = 0; posSlot < p->distTableSize; posSlot++)
  | 
        
        
            | 
            | 
           1681 | 
                 posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices);
  | 
        
        
            | 
            | 
           1682 | 
               for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++)
  | 
        
        
            | 
            | 
           1683 | 
                 posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits);
  | 
        
        
            | 
            | 
           1684 | 
              | 
        
        
            | 
            | 
           1685 | 
               {
  | 
        
        
            | 
            | 
           1686 | 
                 UInt32 *distancesPrices = p->distancesPrices[lenToPosState];
  | 
        
        
            | 
            | 
           1687 | 
                 UInt32 i;
  | 
        
        
            | 
            | 
           1688 | 
                 for (i = 0; i < kStartPosModelIndex; i++)
  | 
        
        
            | 
            | 
           1689 | 
                   distancesPrices[i] = posSlotPrices[i];
  | 
        
        
            | 
            | 
           1690 | 
                 for (; i < kNumFullDistances; i++)
  | 
        
        
            | 
            | 
           1691 | 
                   distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i];
  | 
        
        
            | 
            | 
           1692 | 
               }
  | 
        
        
            | 
            | 
           1693 | 
             }
  | 
        
        
            | 
            | 
           1694 | 
             p->matchPriceCount = 0;
  | 
        
        
            | 
            | 
           1695 | 
           }
  | 
        
        
            | 
            | 
           1696 | 
              | 
        
        
            | 
            | 
           1697 | 
           void LzmaEnc_Construct(CLzmaEnc *p)
  | 
        
        
            | 
            | 
           1698 | 
           {
  | 
        
        
            | 
            | 
           1699 | 
             RangeEnc_Construct(&p->rc);
  | 
        
        
            | 
            | 
           1700 | 
             MatchFinder_Construct(&p->matchFinderBase);
  | 
        
        
            | 
            | 
           1701 | 
             #ifdef COMPRESS_MF_MT
  | 
        
        
            | 
            | 
           1702 | 
             MatchFinderMt_Construct(&p->matchFinderMt);
  | 
        
        
            | 
            | 
           1703 | 
             p->matchFinderMt.MatchFinder = &p->matchFinderBase;
  | 
        
        
            | 
            | 
           1704 | 
             #endif
  | 
        
        
            | 
            | 
           1705 | 
              | 
        
        
            | 
            | 
           1706 | 
             {
  | 
        
        
            | 
            | 
           1707 | 
               CLzmaEncProps props;
  | 
        
        
            | 
            | 
           1708 | 
               LzmaEncProps_Init(&props);
  | 
        
        
            | 
            | 
           1709 | 
               LzmaEnc_SetProps(p, &props);
  | 
        
        
            | 
            | 
           1710 | 
             }
  | 
        
        
            | 
            | 
           1711 | 
              | 
        
        
            | 
            | 
           1712 | 
             #ifndef LZMA_LOG_BSR
  | 
        
        
            | 
            | 
           1713 | 
             LzmaEnc_FastPosInit(p->g_FastPos);
  | 
        
        
            | 
            | 
           1714 | 
             #endif
  | 
        
        
            | 
            | 
           1715 | 
              | 
        
        
            | 
            | 
           1716 | 
             LzmaEnc_InitPriceTables(p->ProbPrices);
  | 
        
        
            | 
            | 
           1717 | 
             p->litProbs = 0;
  | 
        
        
            | 
            | 
           1718 | 
             p->saveState.litProbs = 0;
  | 
        
        
            | 
            | 
           1719 | 
           }
  | 
        
        
            | 
            | 
           1720 | 
              | 
        
        
            | 
            | 
           1721 | 
           CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
  | 
        
        
            | 
            | 
           1722 | 
           {
  | 
        
        
            | 
            | 
           1723 | 
             void *p;
  | 
        
        
            | 
            | 
           1724 | 
             p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
  | 
        
        
            | 
            | 
           1725 | 
             if (p != 0)
  | 
        
        
            | 
            | 
           1726 | 
               LzmaEnc_Construct((CLzmaEnc *)p);
  | 
        
        
            | 
            | 
           1727 | 
             return p;
  | 
        
        
            | 
            | 
           1728 | 
           }
  | 
        
        
            | 
            | 
           1729 | 
              | 
        
        
            | 
            | 
           1730 | 
           void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
  | 
        
        
            | 
            | 
           1731 | 
           {
  | 
        
        
            | 
            | 
           1732 | 
             alloc->Free(alloc, p->litProbs);
  | 
        
        
            | 
            | 
           1733 | 
             alloc->Free(alloc, p->saveState.litProbs);
  | 
        
        
            | 
            | 
           1734 | 
             p->litProbs = 0;
  | 
        
        
            | 
            | 
           1735 | 
             p->saveState.litProbs = 0;
  | 
        
        
            | 
            | 
           1736 | 
           }
  | 
        
        
            | 
            | 
           1737 | 
              | 
        
        
            | 
            | 
           1738 | 
           void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
  | 
        
        
            | 
            | 
           1739 | 
           {
  | 
        
        
            | 
            | 
           1740 | 
             #ifdef COMPRESS_MF_MT
  | 
        
        
            | 
            | 
           1741 | 
             MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
  | 
        
        
            | 
            | 
           1742 | 
             #endif
  | 
        
        
            | 
            | 
           1743 | 
             MatchFinder_Free(&p->matchFinderBase, allocBig);
  | 
        
        
            | 
            | 
           1744 | 
             LzmaEnc_FreeLits(p, alloc);
  | 
        
        
            | 
            | 
           1745 | 
             RangeEnc_Free(&p->rc, alloc);
  | 
        
        
            | 
            | 
           1746 | 
           }
  | 
        
        
            | 
            | 
           1747 | 
              | 
        
        
            | 
            | 
           1748 | 
           void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig)
  | 
        
        
            | 
            | 
           1749 | 
           {
  | 
        
        
            | 
            | 
           1750 | 
             LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig);
  | 
        
        
            | 
            | 
           1751 | 
             alloc->Free(alloc, p);
  | 
        
        
            | 
            | 
           1752 | 
           }
  | 
        
        
            | 
            | 
           1753 | 
              | 
        
        
            | 
            | 
           1754 | 
           static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)
  | 
        
        
            | 
            | 
           1755 | 
           {
  | 
        
        
            | 
            | 
           1756 | 
             UInt32 nowPos32, startPos32;
  | 
        
        
            | 
            | 
           1757 | 
             if (p->inStream != 0)
  | 
        
        
            | 
            | 
           1758 | 
             {
  | 
        
        
            | 
            | 
           1759 | 
               p->matchFinderBase.stream = p->inStream;
  | 
        
        
            | 
            | 
           1760 | 
               p->matchFinder.Init(p->matchFinderObj);
  | 
        
        
            | 
            | 
           1761 | 
               p->inStream = 0;
  | 
        
        
            | 
            | 
           1762 | 
             }
  | 
        
        
            | 
            | 
           1763 | 
              | 
        
        
            | 
            | 
           1764 | 
             if (p->finished)
  | 
        
        
            | 
            | 
           1765 | 
               return p->result;
  | 
        
        
            | 
            | 
           1766 | 
             RINOK(CheckErrors(p));
  | 
        
        
            | 
            | 
           1767 | 
              | 
        
        
            | 
            | 
           1768 | 
             nowPos32 = (UInt32)p->nowPos64;
  | 
        
        
            | 
            | 
           1769 | 
             startPos32 = nowPos32;
  | 
        
        
            | 
            | 
           1770 | 
              | 
        
        
            | 
            | 
           1771 | 
             if (p->nowPos64 == 0)
  | 
        
        
            | 
            | 
           1772 | 
             {
  | 
        
        
            | 
            | 
           1773 | 
               UInt32 numPairs;
  | 
        
        
            | 
            | 
           1774 | 
               Byte curByte;
  | 
        
        
            | 
            | 
           1775 | 
               if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
  | 
        
        
            | 
            | 
           1776 | 
                 return Flush(p, nowPos32);
  | 
        
        
            | 
            | 
           1777 | 
               ReadMatchDistances(p, &numPairs);
  | 
        
        
            | 
            | 
           1778 | 
               RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);
  | 
        
        
            | 
            | 
           1779 | 
               p->state = kLiteralNextStates[p->state];
  | 
        
        
            | 
            | 
           1780 | 
               curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset);
  | 
        
        
            | 
            | 
           1781 | 
               LitEnc_Encode(&p->rc, p->litProbs, curByte);
  | 
        
        
            | 
            | 
           1782 | 
               p->additionalOffset--;
  | 
        
        
            | 
            | 
           1783 | 
               nowPos32++;
  | 
        
        
            | 
            | 
           1784 | 
             }
  | 
        
        
            | 
            | 
           1785 | 
              | 
        
        
            | 
            | 
           1786 | 
             if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0)
  | 
        
        
            | 
            | 
           1787 | 
             for (;;)
  | 
        
        
            | 
            | 
           1788 | 
             {
  | 
        
        
            | 
            | 
           1789 | 
               UInt32 pos, len, posState;
  | 
        
        
            | 
            | 
           1790 | 
              | 
        
        
            | 
            | 
           1791 | 
               if (p->fastMode)
  | 
        
        
            | 
            | 
           1792 | 
                 len = GetOptimumFast(p, &pos);
  | 
        
        
            | 
            | 
           1793 | 
               else
  | 
        
        
            | 
            | 
           1794 | 
                 len = GetOptimum(p, nowPos32, &pos);
  | 
        
        
            | 
            | 
           1795 | 
              | 
        
        
            | 
            | 
           1796 | 
               #ifdef SHOW_STAT2
  | 
        
        
            | 
            | 
           1797 | 
               printf("\n pos = %4X,   len = %d   pos = %d", nowPos32, len, pos);
  | 
        
        
            | 
            | 
           1798 | 
               #endif
  | 
        
        
            | 
            | 
           1799 | 
              | 
        
        
            | 
            | 
           1800 | 
               posState = nowPos32 & p->pbMask;
  | 
        
        
            | 
            | 
           1801 | 
               if (len == 1 && pos == (UInt32)-1)
  | 
        
        
            | 
            | 
           1802 | 
               {
  | 
        
        
            | 
            | 
           1803 | 
                 Byte curByte;
  | 
        
        
            | 
            | 
           1804 | 
                 CLzmaProb *probs;
  | 
        
        
            | 
            | 
           1805 | 
                 const Byte *data;
  | 
        
        
            | 
            | 
           1806 | 
              | 
        
        
            | 
            | 
           1807 | 
                 RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0);
  | 
        
        
            | 
            | 
           1808 | 
                 data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
  | 
        
        
            | 
            | 
           1809 | 
                 curByte = *data;
  | 
        
        
            | 
            | 
           1810 | 
                 probs = LIT_PROBS(nowPos32, *(data - 1));
  | 
        
        
            | 
            | 
           1811 | 
                 if (IsCharState(p->state))
  | 
        
        
            | 
            | 
           1812 | 
                   LitEnc_Encode(&p->rc, probs, curByte);
  | 
        
        
            | 
            | 
           1813 | 
                 else
  | 
        
        
            | 
            | 
           1814 | 
                   LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1));
  | 
        
        
            | 
            | 
           1815 | 
                 p->state = kLiteralNextStates[p->state];
  | 
        
        
            | 
            | 
           1816 | 
               }
  | 
        
        
            | 
            | 
           1817 | 
               else
  | 
        
        
            | 
            | 
           1818 | 
               {
  | 
        
        
            | 
            | 
           1819 | 
                 RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
  | 
        
        
            | 
            | 
           1820 | 
                 if (pos < LZMA_NUM_REPS)
  | 
        
        
            | 
            | 
           1821 | 
                 {
  | 
        
        
            | 
            | 
           1822 | 
                   RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1);
  | 
        
        
            | 
            | 
           1823 | 
                   if (pos == 0)
  | 
        
        
            | 
            | 
           1824 | 
                   {
  | 
        
        
            | 
            | 
           1825 | 
                     RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0);
  | 
        
        
            | 
            | 
           1826 | 
                     RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1));
  | 
        
        
            | 
            | 
           1827 | 
                   }
  | 
        
        
            | 
            | 
           1828 | 
                   else
  | 
        
        
            | 
            | 
           1829 | 
                   {
  | 
        
        
            | 
            | 
           1830 | 
                     UInt32 distance = p->reps[pos];
  | 
        
        
            | 
            | 
           1831 | 
                     RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1);
  | 
        
        
            | 
            | 
           1832 | 
                     if (pos == 1)
  | 
        
        
            | 
            | 
           1833 | 
                       RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0);
  | 
        
        
            | 
            | 
           1834 | 
                     else
  | 
        
        
            | 
            | 
           1835 | 
                     {
  | 
        
        
            | 
            | 
           1836 | 
                       RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1);
  | 
        
        
            | 
            | 
           1837 | 
                       RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2);
  | 
        
        
            | 
            | 
           1838 | 
                       if (pos == 3)
  | 
        
        
            | 
            | 
           1839 | 
                         p->reps[3] = p->reps[2];
  | 
        
        
            | 
            | 
           1840 | 
                       p->reps[2] = p->reps[1];
  | 
        
        
            | 
            | 
           1841 | 
                     }
  | 
        
        
            | 
            | 
           1842 | 
                     p->reps[1] = p->reps[0];
  | 
        
        
            | 
            | 
           1843 | 
                     p->reps[0] = distance;
  | 
        
        
            | 
            | 
           1844 | 
                   }
  | 
        
        
            | 
            | 
           1845 | 
                   if (len == 1)
  | 
        
        
            | 
            | 
           1846 | 
                     p->state = kShortRepNextStates[p->state];
  | 
        
        
            | 
            | 
           1847 | 
                   else
  | 
        
        
            | 
            | 
           1848 | 
                   {
  | 
        
        
            | 
            | 
           1849 | 
                     LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
  | 
        
        
            | 
            | 
           1850 | 
                     p->state = kRepNextStates[p->state];
  | 
        
        
            | 
            | 
           1851 | 
                   }
  | 
        
        
            | 
            | 
           1852 | 
                 }
  | 
        
        
            | 
            | 
           1853 | 
                 else
  | 
        
        
            | 
            | 
           1854 | 
                 {
  | 
        
        
            | 
            | 
           1855 | 
                   UInt32 posSlot;
  | 
        
        
            | 
            | 
           1856 | 
                   RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
  | 
        
        
            | 
            | 
           1857 | 
                   p->state = kMatchNextStates[p->state];
  | 
        
        
            | 
            | 
           1858 | 
                   LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
  | 
        
        
            | 
            | 
           1859 | 
                   pos -= LZMA_NUM_REPS;
  | 
        
        
            | 
            | 
           1860 | 
                   GetPosSlot(pos, posSlot);
  | 
        
        
            | 
            | 
           1861 | 
                   RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);
  | 
        
        
            | 
            | 
           1862 | 
              | 
        
        
            | 
            | 
           1863 | 
                   if (posSlot >= kStartPosModelIndex)
  | 
        
        
            | 
            | 
           1864 | 
                   {
  | 
        
        
            | 
            | 
           1865 | 
                     UInt32 footerBits = ((posSlot >> 1) - 1);
  | 
        
        
            | 
            | 
           1866 | 
                     UInt32 base = ((2 | (posSlot & 1)) << footerBits);
  | 
        
        
            | 
            | 
           1867 | 
                     UInt32 posReduced = pos - base;
  | 
        
        
            | 
            | 
           1868 | 
              | 
        
        
            | 
            | 
           1869 | 
                     if (posSlot < kEndPosModelIndex)
  | 
        
        
            | 
            | 
           1870 | 
                       RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced);
  | 
        
        
            | 
            | 
           1871 | 
                     else
  | 
        
        
            | 
            | 
           1872 | 
                     {
  | 
        
        
            | 
            | 
           1873 | 
                       RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
  | 
        
        
            | 
            | 
           1874 | 
                       RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);
  | 
        
        
            | 
            | 
           1875 | 
                       p->alignPriceCount++;
  | 
        
        
            | 
            | 
           1876 | 
                     }
  | 
        
        
            | 
            | 
           1877 | 
                   }
  | 
        
        
            | 
            | 
           1878 | 
                   p->reps[3] = p->reps[2];
  | 
        
        
            | 
            | 
           1879 | 
                   p->reps[2] = p->reps[1];
  | 
        
        
            | 
            | 
           1880 | 
                   p->reps[1] = p->reps[0];
  | 
        
        
            | 
            | 
           1881 | 
                   p->reps[0] = pos;
  | 
        
        
            | 
            | 
           1882 | 
                   p->matchPriceCount++;
  | 
        
        
            | 
            | 
           1883 | 
                 }
  | 
        
        
            | 
            | 
           1884 | 
               }
  | 
        
        
            | 
            | 
           1885 | 
               p->additionalOffset -= len;
  | 
        
        
            | 
            | 
           1886 | 
               nowPos32 += len;
  | 
        
        
            | 
            | 
           1887 | 
               if (p->additionalOffset == 0)
  | 
        
        
            | 
            | 
           1888 | 
               {
  | 
        
        
            | 
            | 
           1889 | 
                 UInt32 processed;
  | 
        
        
            | 
            | 
           1890 | 
                 if (!p->fastMode)
  | 
        
        
            | 
            | 
           1891 | 
                 {
  | 
        
        
            | 
            | 
           1892 | 
                   if (p->matchPriceCount >= (1 << 7))
  | 
        
        
            | 
            | 
           1893 | 
                     FillDistancesPrices(p);
  | 
        
        
            | 
            | 
           1894 | 
                   if (p->alignPriceCount >= kAlignTableSize)
  | 
        
        
            | 
            | 
           1895 | 
                     FillAlignPrices(p);
  | 
        
        
            | 
            | 
           1896 | 
                 }
  | 
        
        
            | 
            | 
           1897 | 
                 if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
  | 
        
        
            | 
            | 
           1898 | 
                   break;
  | 
        
        
            | 
            | 
           1899 | 
                 processed = nowPos32 - startPos32;
  | 
        
        
            | 
            | 
           1900 | 
                 if (useLimits)
  | 
        
        
            | 
            | 
           1901 | 
                 {
  | 
        
        
            | 
            | 
           1902 | 
                   if (processed + kNumOpts + 300 >= maxUnpackSize ||
  | 
        
        
            | 
            | 
           1903 | 
                       RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)
  | 
        
        
            | 
            | 
           1904 | 
                     break;
  | 
        
        
            | 
            | 
           1905 | 
                 }
  | 
        
        
            | 
            | 
           1906 | 
                 else if (processed >= (1 << 15))
  | 
        
        
            | 
            | 
           1907 | 
                 {
  | 
        
        
            | 
            | 
           1908 | 
                   p->nowPos64 += nowPos32 - startPos32;
  | 
        
        
            | 
            | 
           1909 | 
                   return CheckErrors(p);
  | 
        
        
            | 
            | 
           1910 | 
                 }
  | 
        
        
            | 
            | 
           1911 | 
               }
  | 
        
        
            | 
            | 
           1912 | 
             }
  | 
        
        
            | 
            | 
           1913 | 
             p->nowPos64 += nowPos32 - startPos32;
  | 
        
        
            | 
            | 
           1914 | 
             return Flush(p, nowPos32);
  | 
        
        
            | 
            | 
           1915 | 
           }
  | 
        
        
            | 
            | 
           1916 | 
              | 
        
        
            | 
            | 
           1917 | 
           #define kBigHashDicLimit ((UInt32)1 << 24)
  | 
        
        
            | 
            | 
           1918 | 
              | 
        
        
            | 
            | 
           1919 | 
           static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
  | 
        
        
            | 
            | 
           1920 | 
           {
  | 
        
        
            | 
            | 
           1921 | 
             UInt32 beforeSize = kNumOpts;
  | 
        
        
            | 
            | 
           1922 | 
             Bool btMode;
  | 
        
        
            | 
            | 
           1923 | 
             if (!RangeEnc_Alloc(&p->rc, alloc))
  | 
        
        
            | 
            | 
           1924 | 
               return SZ_ERROR_MEM;
  | 
        
        
            | 
            | 
           1925 | 
             btMode = (p->matchFinderBase.btMode != 0);
  | 
        
        
            | 
            | 
           1926 | 
             #ifdef COMPRESS_MF_MT
  | 
        
        
            | 
            | 
           1927 | 
             p->mtMode = (p->multiThread && !p->fastMode && btMode);
  | 
        
        
            | 
            | 
           1928 | 
             #endif
  | 
        
        
            | 
            | 
           1929 | 
              | 
        
        
            | 
            | 
           1930 | 
             {
  | 
        
        
            | 
            | 
           1931 | 
               unsigned lclp = p->lc + p->lp;
  | 
        
        
            | 
            | 
           1932 | 
               if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp)
  | 
        
        
            | 
            | 
           1933 | 
               {
  | 
        
        
            | 
            | 
           1934 | 
                 LzmaEnc_FreeLits(p, alloc);
  | 
        
        
            | 
            | 
           1935 | 
                 p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
  | 
        
        
            | 
            | 
           1936 | 
                 p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
  | 
        
        
            | 
            | 
           1937 | 
                 if (p->litProbs == 0 || p->saveState.litProbs == 0)
  | 
        
        
            | 
            | 
           1938 | 
                 {
  | 
        
        
            | 
            | 
           1939 | 
                   LzmaEnc_FreeLits(p, alloc);
  | 
        
        
            | 
            | 
           1940 | 
                   return SZ_ERROR_MEM;
  | 
        
        
            | 
            | 
           1941 | 
                 }
  | 
        
        
            | 
            | 
           1942 | 
                 p->lclp = lclp;
  | 
        
        
            | 
            | 
           1943 | 
               }
  | 
        
        
            | 
            | 
           1944 | 
             }
  | 
        
        
            | 
            | 
           1945 | 
              | 
        
        
            | 
            | 
           1946 | 
             p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit);
  | 
        
        
            | 
            | 
           1947 | 
              | 
        
        
            | 
            | 
           1948 | 
             if (beforeSize + p->dictSize < keepWindowSize)
  | 
        
        
            | 
            | 
           1949 | 
               beforeSize = keepWindowSize - p->dictSize;
  | 
        
        
            | 
            | 
           1950 | 
              | 
        
        
            | 
            | 
           1951 | 
             #ifdef COMPRESS_MF_MT
  | 
        
        
            | 
            | 
           1952 | 
             if (p->mtMode)
  | 
        
        
            | 
            | 
           1953 | 
             {
  | 
        
        
            | 
            | 
           1954 | 
               RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig));
  | 
        
        
            | 
            | 
           1955 | 
               p->matchFinderObj = &p->matchFinderMt;
  | 
        
        
            | 
            | 
           1956 | 
               MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
  | 
        
        
            | 
            | 
           1957 | 
             }
  | 
        
        
            | 
            | 
           1958 | 
             else
  | 
        
        
            | 
            | 
           1959 | 
             #endif
  | 
        
        
            | 
            | 
           1960 | 
             {
  | 
        
        
            | 
            | 
           1961 | 
               if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig))
  | 
        
        
            | 
            | 
           1962 | 
                 return SZ_ERROR_MEM;
  | 
        
        
            | 
            | 
           1963 | 
               p->matchFinderObj = &p->matchFinderBase;
  | 
        
        
            | 
            | 
           1964 | 
               MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder);
  | 
        
        
            | 
            | 
           1965 | 
             }
  | 
        
        
            | 
            | 
           1966 | 
             return SZ_OK;
  | 
        
        
            | 
            | 
           1967 | 
           }
  | 
        
        
            | 
            | 
           1968 | 
              | 
        
        
            | 
            | 
           1969 | 
           void LzmaEnc_Init(CLzmaEnc *p)
  | 
        
        
            | 
            | 
           1970 | 
           {
  | 
        
        
            | 
            | 
           1971 | 
             UInt32 i;
  | 
        
        
            | 
            | 
           1972 | 
             p->state = 0;
  | 
        
        
            | 
            | 
           1973 | 
             for (i = 0 ; i < LZMA_NUM_REPS; i++)
  | 
        
        
            | 
            | 
           1974 | 
               p->reps[i] = 0;
  | 
        
        
            | 
            | 
           1975 | 
              | 
        
        
            | 
            | 
           1976 | 
             RangeEnc_Init(&p->rc);
  | 
        
        
            | 
            | 
           1977 | 
              | 
        
        
            | 
            | 
           1978 | 
              | 
        
        
            | 
            | 
           1979 | 
             for (i = 0; i < kNumStates; i++)
  | 
        
        
            | 
            | 
           1980 | 
             {
  | 
        
        
            | 
            | 
           1981 | 
               UInt32 j;
  | 
        
        
            | 
            | 
           1982 | 
               for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++)
  | 
        
        
            | 
            | 
           1983 | 
               {
  | 
        
        
            | 
            | 
           1984 | 
                 p->isMatch[i][j] = kProbInitValue;
  | 
        
        
            | 
            | 
           1985 | 
                 p->isRep0Long[i][j] = kProbInitValue;
  | 
        
        
            | 
            | 
           1986 | 
               }
  | 
        
        
            | 
            | 
           1987 | 
               p->isRep[i] = kProbInitValue;
  | 
        
        
            | 
            | 
           1988 | 
               p->isRepG0[i] = kProbInitValue;
  | 
        
        
            | 
            | 
           1989 | 
               p->isRepG1[i] = kProbInitValue;
  | 
        
        
            | 
            | 
           1990 | 
               p->isRepG2[i] = kProbInitValue;
  | 
        
        
            | 
            | 
           1991 | 
             }
  | 
        
        
            | 
            | 
           1992 | 
              | 
        
        
            | 
            | 
           1993 | 
             {
  | 
        
        
            | 
            | 
           1994 | 
               UInt32 num = 0x300 << (p->lp + p->lc);
  | 
        
        
            | 
            | 
           1995 | 
               for (i = 0; i < num; i++)
  | 
        
        
            | 
            | 
           1996 | 
                 p->litProbs[i] = kProbInitValue;
  | 
        
        
            | 
            | 
           1997 | 
             }
  | 
        
        
            | 
            | 
           1998 | 
              | 
        
        
            | 
            | 
           1999 | 
             {
  | 
        
        
            | 
            | 
           2000 | 
               for (i = 0; i < kNumLenToPosStates; i++)
  | 
        
        
            | 
            | 
           2001 | 
               {
  | 
        
        
            | 
            | 
           2002 | 
                 CLzmaProb *probs = p->posSlotEncoder[i];
  | 
        
        
            | 
            | 
           2003 | 
                 UInt32 j;
  | 
        
        
            | 
            | 
           2004 | 
                 for (j = 0; j < (1 << kNumPosSlotBits); j++)
  | 
        
        
            | 
            | 
           2005 | 
                   probs[j] = kProbInitValue;
  | 
        
        
            | 
            | 
           2006 | 
               }
  | 
        
        
            | 
            | 
           2007 | 
             }
  | 
        
        
            | 
            | 
           2008 | 
             {
  | 
        
        
            | 
            | 
           2009 | 
               for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
  | 
        
        
            | 
            | 
           2010 | 
                 p->posEncoders[i] = kProbInitValue;
  | 
        
        
            | 
            | 
           2011 | 
             }
  | 
        
        
            | 
            | 
           2012 | 
              | 
        
        
            | 
            | 
           2013 | 
             LenEnc_Init(&p->lenEnc.p);
  | 
        
        
            | 
            | 
           2014 | 
             LenEnc_Init(&p->repLenEnc.p);
  | 
        
        
            | 
            | 
           2015 | 
              | 
        
        
            | 
            | 
           2016 | 
             for (i = 0; i < (1 << kNumAlignBits); i++)
  | 
        
        
            | 
            | 
           2017 | 
               p->posAlignEncoder[i] = kProbInitValue;
  | 
        
        
            | 
            | 
           2018 | 
              | 
        
        
            | 
            | 
           2019 | 
             p->optimumEndIndex = 0;
  | 
        
        
            | 
            | 
           2020 | 
             p->optimumCurrentIndex = 0;
  | 
        
        
            | 
            | 
           2021 | 
             p->additionalOffset = 0;
  | 
        
        
            | 
            | 
           2022 | 
              | 
        
        
            | 
            | 
           2023 | 
             p->pbMask = (1 << p->pb) - 1;
  | 
        
        
            | 
            | 
           2024 | 
             p->lpMask = (1 << p->lp) - 1;
  | 
        
        
            | 
            | 
           2025 | 
           }
  | 
        
        
            | 
            | 
           2026 | 
              | 
        
        
            | 
            | 
           2027 | 
           void LzmaEnc_InitPrices(CLzmaEnc *p)
  | 
        
        
            | 
            | 
           2028 | 
           {
  | 
        
        
            | 
            | 
           2029 | 
             if (!p->fastMode)
  | 
        
        
            | 
            | 
           2030 | 
             {
  | 
        
        
            | 
            | 
           2031 | 
               FillDistancesPrices(p);
  | 
        
        
            | 
            | 
           2032 | 
               FillAlignPrices(p);
  | 
        
        
            | 
            | 
           2033 | 
             }
  | 
        
        
            | 
            | 
           2034 | 
              | 
        
        
            | 
            | 
           2035 | 
             p->lenEnc.tableSize =
  | 
        
        
            | 
            | 
           2036 | 
             p->repLenEnc.tableSize =
  | 
        
        
            | 
            | 
           2037 | 
                 p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN;
  | 
        
        
            | 
            | 
           2038 | 
             LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices);
  | 
        
        
            | 
            | 
           2039 | 
             LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices);
  | 
        
        
            | 
            | 
           2040 | 
           }
  | 
        
        
            | 
            | 
           2041 | 
              | 
        
        
            | 
            | 
           2042 | 
           static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
  | 
        
        
            | 
            | 
           2043 | 
           {
  | 
        
        
            | 
            | 
           2044 | 
             UInt32 i;
  | 
        
        
            | 
            | 
           2045 | 
             for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++)
  | 
        
        
            | 
            | 
           2046 | 
               if (p->dictSize <= ((UInt32)1 << i))
  | 
        
        
            | 
            | 
           2047 | 
                 break;
  | 
        
        
            | 
            | 
           2048 | 
             p->distTableSize = i * 2;
  | 
        
        
            | 
            | 
           2049 | 
              | 
        
        
            | 
            | 
           2050 | 
             p->finished = False;
  | 
        
        
            | 
            | 
           2051 | 
             p->result = SZ_OK;
  | 
        
        
            | 
            | 
           2052 | 
             RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig));
  | 
        
        
            | 
            | 
           2053 | 
             LzmaEnc_Init(p);
  | 
        
        
            | 
            | 
           2054 | 
             LzmaEnc_InitPrices(p);
  | 
        
        
            | 
            | 
           2055 | 
             p->nowPos64 = 0;
  | 
        
        
            | 
            | 
           2056 | 
             return SZ_OK;
  | 
        
        
            | 
            | 
           2057 | 
           }
  | 
        
        
            | 
            | 
           2058 | 
              | 
        
        
            | 
            | 
           2059 | 
           static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqInStream *inStream, ISeqOutStream *outStream,
  | 
        
        
            | 
            | 
           2060 | 
               ISzAlloc *alloc, ISzAlloc *allocBig)
  | 
        
        
            | 
            | 
           2061 | 
           {
  | 
        
        
            | 
            | 
           2062 | 
             CLzmaEnc *p = (CLzmaEnc *)pp;
  | 
        
        
            | 
            | 
           2063 | 
             p->inStream = inStream;
  | 
        
        
            | 
            | 
           2064 | 
             p->rc.outStream = outStream;
  | 
        
        
            | 
            | 
           2065 | 
             return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig);
  | 
        
        
            | 
            | 
           2066 | 
           }
  | 
        
        
            | 
            | 
           2067 | 
              | 
        
        
            | 
            | 
           2068 | 
           SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
  | 
        
        
            | 
            | 
           2069 | 
               ISeqInStream *inStream, UInt32 keepWindowSize,
  | 
        
        
            | 
            | 
           2070 | 
               ISzAlloc *alloc, ISzAlloc *allocBig)
  | 
        
        
            | 
            | 
           2071 | 
           {
  | 
        
        
            | 
            | 
           2072 | 
             CLzmaEnc *p = (CLzmaEnc *)pp;
  | 
        
        
            | 
            | 
           2073 | 
             p->inStream = inStream;
  | 
        
        
            | 
            | 
           2074 | 
             return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
  | 
        
        
            | 
            | 
           2075 | 
           }
  | 
        
        
            | 
            | 
           2076 | 
              | 
        
        
            | 
            | 
           2077 | 
           static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)
  | 
        
        
            | 
            | 
           2078 | 
           {
  | 
        
        
            | 
            | 
           2079 | 
             p->seqBufInStream.funcTable.Read = MyRead;
  | 
        
        
            | 
            | 
           2080 | 
             p->seqBufInStream.data = src;
  | 
        
        
            | 
            | 
           2081 | 
             p->seqBufInStream.rem = srcLen;
  | 
        
        
            | 
            | 
           2082 | 
           }
  | 
        
        
            | 
            | 
           2083 | 
              | 
        
        
            | 
            | 
           2084 | 
           SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
  | 
        
        
            | 
            | 
           2085 | 
               UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
  | 
        
        
            | 
            | 
           2086 | 
           {
  | 
        
        
            | 
            | 
           2087 | 
             CLzmaEnc *p = (CLzmaEnc *)pp;
  | 
        
        
            | 
            | 
           2088 | 
             LzmaEnc_SetInputBuf(p, src, srcLen);
  | 
        
        
            | 
            | 
           2089 | 
             p->inStream = &p->seqBufInStream.funcTable;
  | 
        
        
            | 
            | 
           2090 | 
             return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
  | 
        
        
            | 
            | 
           2091 | 
           }
  | 
        
        
            | 
            | 
           2092 | 
              | 
        
        
            | 
            | 
           2093 | 
           void LzmaEnc_Finish(CLzmaEncHandle pp)
  | 
        
        
            | 
            | 
           2094 | 
           {
  | 
        
        
            | 
            | 
           2095 | 
             #ifdef COMPRESS_MF_MT
  | 
        
        
            | 
            | 
           2096 | 
             CLzmaEnc *p = (CLzmaEnc *)pp;
  | 
        
        
            | 
            | 
           2097 | 
             if (p->mtMode)
  | 
        
        
            | 
            | 
           2098 | 
               MatchFinderMt_ReleaseStream(&p->matchFinderMt);
  | 
        
        
            | 
            | 
           2099 | 
             #else
  | 
        
        
            | 
            | 
           2100 | 
             pp = pp;
  | 
        
        
            | 
            | 
           2101 | 
             #endif
  | 
        
        
            | 
            | 
           2102 | 
           }
  | 
        
        
            | 
            | 
           2103 | 
              | 
        
        
            | 
            | 
           2104 | 
           typedef struct _CSeqOutStreamBuf
  | 
        
        
            | 
            | 
           2105 | 
           {
  | 
        
        
            | 
            | 
           2106 | 
             ISeqOutStream funcTable;
  | 
        
        
            | 
            | 
           2107 | 
             Byte *data;
  | 
        
        
            | 
            | 
           2108 | 
             SizeT rem;
  | 
        
        
            | 
            | 
           2109 | 
             Bool overflow;
  | 
        
        
            | 
            | 
           2110 | 
           } CSeqOutStreamBuf;
  | 
        
        
            | 
            | 
           2111 | 
              | 
        
        
            | 
            | 
           2112 | 
           static size_t MyWrite(void *pp, const void *data, size_t size)
  | 
        
        
            | 
            | 
           2113 | 
           {
  | 
        
        
            | 
            | 
           2114 | 
             CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp;
  | 
        
        
            | 
            | 
           2115 | 
             if (p->rem < size)
  | 
        
        
            | 
            | 
           2116 | 
             {
  | 
        
        
            | 
            | 
           2117 | 
               size = p->rem;
  | 
        
        
            | 
            | 
           2118 | 
               p->overflow = True;
  | 
        
        
            | 
            | 
           2119 | 
             }
  | 
        
        
            | 
            | 
           2120 | 
             memcpy(p->data, data, size);
  | 
        
        
            | 
            | 
           2121 | 
             p->rem -= size;
  | 
        
        
            | 
            | 
           2122 | 
             p->data += size;
  | 
        
        
            | 
            | 
           2123 | 
             return size;
  | 
        
        
            | 
            | 
           2124 | 
           }
  | 
        
        
            | 
            | 
           2125 | 
              | 
        
        
            | 
            | 
           2126 | 
              | 
        
        
            | 
            | 
           2127 | 
           UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
  | 
        
        
            | 
            | 
           2128 | 
           {
  | 
        
        
            | 
            | 
           2129 | 
             const CLzmaEnc *p = (CLzmaEnc *)pp;
  | 
        
        
            | 
            | 
           2130 | 
             return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
  | 
        
        
            | 
            | 
           2131 | 
           }
  | 
        
        
            | 
            | 
           2132 | 
              | 
        
        
            | 
            | 
           2133 | 
           const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
  | 
        
        
            | 
            | 
           2134 | 
           {
  | 
        
        
            | 
            | 
           2135 | 
             const CLzmaEnc *p = (CLzmaEnc *)pp;
  | 
        
        
            | 
            | 
           2136 | 
             return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
  | 
        
        
            | 
            | 
           2137 | 
           }
  | 
        
        
            | 
            | 
           2138 | 
              | 
        
        
            | 
            | 
           2139 | 
           SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
  | 
        
        
            | 
            | 
           2140 | 
               Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
  | 
        
        
            | 
            | 
           2141 | 
           {
  | 
        
        
            | 
            | 
           2142 | 
             CLzmaEnc *p = (CLzmaEnc *)pp;
  | 
        
        
            | 
            | 
           2143 | 
             UInt64 nowPos64;
  | 
        
        
            | 
            | 
           2144 | 
             SRes res;
  | 
        
        
            | 
            | 
           2145 | 
             CSeqOutStreamBuf outStream;
  | 
        
        
            | 
            | 
           2146 | 
              | 
        
        
            | 
            | 
           2147 | 
             outStream.funcTable.Write = MyWrite;
  | 
        
        
            | 
            | 
           2148 | 
             outStream.data = dest;
  | 
        
        
            | 
            | 
           2149 | 
             outStream.rem = *destLen;
  | 
        
        
            | 
            | 
           2150 | 
             outStream.overflow = False;
  | 
        
        
            | 
            | 
           2151 | 
              | 
        
        
            | 
            | 
           2152 | 
             p->writeEndMark = False;
  | 
        
        
            | 
            | 
           2153 | 
             p->finished = False;
  | 
        
        
            | 
            | 
           2154 | 
             p->result = SZ_OK;
  | 
        
        
            | 
            | 
           2155 | 
              | 
        
        
            | 
            | 
           2156 | 
             if (reInit)
  | 
        
        
            | 
            | 
           2157 | 
               LzmaEnc_Init(p);
  | 
        
        
            | 
            | 
           2158 | 
             LzmaEnc_InitPrices(p);
  | 
        
        
            | 
            | 
           2159 | 
             nowPos64 = p->nowPos64;
  | 
        
        
            | 
            | 
           2160 | 
             RangeEnc_Init(&p->rc);
  | 
        
        
            | 
            | 
           2161 | 
             p->rc.outStream = &outStream.funcTable;
  | 
        
        
            | 
            | 
           2162 | 
              | 
        
        
            | 
            | 
           2163 | 
             res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize);
  | 
        
        
            | 
            | 
           2164 | 
              | 
        
        
            | 
            | 
           2165 | 
             *unpackSize = (UInt32)(p->nowPos64 - nowPos64);
  | 
        
        
            | 
            | 
           2166 | 
             *destLen -= outStream.rem;
  | 
        
        
            | 
            | 
           2167 | 
             if (outStream.overflow)
  | 
        
        
            | 
            | 
           2168 | 
               return SZ_ERROR_OUTPUT_EOF;
  | 
        
        
            | 
            | 
           2169 | 
              | 
        
        
            | 
            | 
           2170 | 
             return res;
  | 
        
        
            | 
            | 
           2171 | 
           }
  | 
        
        
            | 
            | 
           2172 | 
              | 
        
        
            | 
            | 
           2173 | 
           SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
  | 
        
        
            | 
            | 
           2174 | 
               ISzAlloc *alloc, ISzAlloc *allocBig)
  | 
        
        
            | 
            | 
           2175 | 
           {
  | 
        
        
            | 
            | 
           2176 | 
             CLzmaEnc *p = (CLzmaEnc *)pp;
  | 
        
        
            | 
            | 
           2177 | 
             SRes res = SZ_OK;
  | 
        
        
            | 
            | 
           2178 | 
              | 
        
        
            | 
            | 
           2179 | 
             #ifdef COMPRESS_MF_MT
  | 
        
        
            | 
            | 
           2180 | 
             Byte allocaDummy[0x300];
  | 
        
        
            | 
            | 
           2181 | 
             int i = 0;
  | 
        
        
            | 
            | 
           2182 | 
             for (i = 0; i < 16; i++)
  | 
        
        
            | 
            | 
           2183 | 
               allocaDummy[i] = (Byte)i;
  | 
        
        
            | 
            | 
           2184 | 
             #endif
  | 
        
        
            | 
            | 
           2185 | 
              | 
        
        
            | 
            | 
           2186 | 
             RINOK(LzmaEnc_Prepare(pp, inStream, outStream, alloc, allocBig));
  | 
        
        
            | 
            | 
           2187 | 
              | 
        
        
            | 
            | 
           2188 | 
             for (;;)
  | 
        
        
            | 
            | 
           2189 | 
             {
  | 
        
        
            | 
            | 
           2190 | 
               res = LzmaEnc_CodeOneBlock(p, False, 0, 0);
  | 
        
        
            | 
            | 
           2191 | 
               if (res != SZ_OK || p->finished != 0)
  | 
        
        
            | 
            | 
           2192 | 
                 break;
  | 
        
        
            | 
            | 
           2193 | 
               if (progress != 0)
  | 
        
        
            | 
            | 
           2194 | 
               {
  | 
        
        
            | 
            | 
           2195 | 
                 res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
  | 
        
        
            | 
            | 
           2196 | 
                 if (res != SZ_OK)
  | 
        
        
            | 
            | 
           2197 | 
                 {
  | 
        
        
            | 
            | 
           2198 | 
                   res = SZ_ERROR_PROGRESS;
  | 
        
        
            | 
            | 
           2199 | 
                   break;
  | 
        
        
            | 
            | 
           2200 | 
                 }
  | 
        
        
            | 
            | 
           2201 | 
               }
  | 
        
        
            | 
            | 
           2202 | 
             }
  | 
        
        
            | 
            | 
           2203 | 
             LzmaEnc_Finish(pp);
  | 
        
        
            | 
            | 
           2204 | 
             return res;
  | 
        
        
            | 
            | 
           2205 | 
           }
  | 
        
        
            | 
            | 
           2206 | 
              | 
        
        
            | 
            | 
           2207 | 
           SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
  | 
        
        
            | 
            | 
           2208 | 
           {
  | 
        
        
            | 
            | 
           2209 | 
             CLzmaEnc *p = (CLzmaEnc *)pp;
  | 
        
        
            | 
            | 
           2210 | 
             int i;
  | 
        
        
            | 
            | 
           2211 | 
             UInt32 dictSize = p->dictSize;
  | 
        
        
            | 
            | 
           2212 | 
             if (*size < LZMA_PROPS_SIZE)
  | 
        
        
            | 
            | 
           2213 | 
               return SZ_ERROR_PARAM;
  | 
        
        
            | 
            | 
           2214 | 
             *size = LZMA_PROPS_SIZE;
  | 
        
        
            | 
            | 
           2215 | 
             props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
  | 
        
        
            | 
            | 
           2216 | 
              | 
        
        
            | 
            | 
           2217 | 
             for (i = 11; i <= 30; i++)
  | 
        
        
            | 
            | 
           2218 | 
             {
  | 
        
        
            | 
            | 
           2219 | 
               if (dictSize <= ((UInt32)2 << i))
  | 
        
        
            | 
            | 
           2220 | 
               {
  | 
        
        
            | 
            | 
           2221 | 
                 dictSize = (2 << i);
  | 
        
        
            | 
            | 
           2222 | 
                 break;
  | 
        
        
            | 
            | 
           2223 | 
               }
  | 
        
        
            | 
            | 
           2224 | 
               if (dictSize <= ((UInt32)3 << i))
  | 
        
        
            | 
            | 
           2225 | 
               {
  | 
        
        
            | 
            | 
           2226 | 
                 dictSize = (3 << i);
  | 
        
        
            | 
            | 
           2227 | 
                 break;
  | 
        
        
            | 
            | 
           2228 | 
               }
  | 
        
        
            | 
            | 
           2229 | 
             }
  | 
        
        
            | 
            | 
           2230 | 
              | 
        
        
            | 
            | 
           2231 | 
             for (i = 0; i < 4; i++)
  | 
        
        
            | 
            | 
           2232 | 
               props[1 + i] = (Byte)(dictSize >> (8 * i));
  | 
        
        
            | 
            | 
           2233 | 
             return SZ_OK;
  | 
        
        
            | 
            | 
           2234 | 
           }
  | 
        
        
            | 
            | 
           2235 | 
              | 
        
        
            | 
            | 
           2236 | 
           SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
  | 
        
        
            | 
            | 
           2237 | 
               int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
  | 
        
        
            | 
            | 
           2238 | 
           {
  | 
        
        
            | 
            | 
           2239 | 
             SRes res;
  | 
        
        
            | 
            | 
           2240 | 
             CLzmaEnc *p = (CLzmaEnc *)pp;
  | 
        
        
            | 
            | 
           2241 | 
              | 
        
        
            | 
            | 
           2242 | 
             CSeqOutStreamBuf outStream;
  | 
        
        
            | 
            | 
           2243 | 
              | 
        
        
            | 
            | 
           2244 | 
             LzmaEnc_SetInputBuf(p, src, srcLen);
  | 
        
        
            | 
            | 
           2245 | 
              | 
        
        
            | 
            | 
           2246 | 
             outStream.funcTable.Write = MyWrite;
  | 
        
        
            | 
            | 
           2247 | 
             outStream.data = dest;
  | 
        
        
            | 
            | 
           2248 | 
             outStream.rem = *destLen;
  | 
        
        
            | 
            | 
           2249 | 
             outStream.overflow = False;
  | 
        
        
            | 
            | 
           2250 | 
              | 
        
        
            | 
            | 
           2251 | 
             p->writeEndMark = writeEndMark;
  | 
        
        
            | 
            | 
           2252 | 
             res = LzmaEnc_Encode(pp, &outStream.funcTable, &p->seqBufInStream.funcTable,
  | 
        
        
            | 
            | 
           2253 | 
                 progress, alloc, allocBig);
  | 
        
        
            | 
            | 
           2254 | 
              | 
        
        
            | 
            | 
           2255 | 
             *destLen -= outStream.rem;
  | 
        
        
            | 
            | 
           2256 | 
             if (outStream.overflow)
  | 
        
        
            | 
            | 
           2257 | 
               return SZ_ERROR_OUTPUT_EOF;
  | 
        
        
            | 
            | 
           2258 | 
             return res;
  | 
        
        
            | 
            | 
           2259 | 
           }
  | 
        
        
            | 
            | 
           2260 | 
              | 
        
        
            | 
            | 
           2261 | 
           SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
  | 
        
        
            | 
            | 
           2262 | 
               const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
  | 
        
        
            | 
            | 
           2263 | 
               ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
  | 
        
        
            | 
            | 
           2264 | 
           {
  | 
        
        
            | 
            | 
           2265 | 
             CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
  | 
        
        
            | 
            | 
           2266 | 
             SRes res;
  | 
        
        
            | 
            | 
           2267 | 
             if (p == 0)
  | 
        
        
            | 
            | 
           2268 | 
               return SZ_ERROR_MEM;
  | 
        
        
            | 
            | 
           2269 | 
              | 
        
        
            | 
            | 
           2270 | 
             res = LzmaEnc_SetProps(p, props);
  | 
        
        
            | 
            | 
           2271 | 
             if (res == SZ_OK)
  | 
        
        
            | 
            | 
           2272 | 
             {
  | 
        
        
            | 
            | 
           2273 | 
               res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize);
  | 
        
        
            | 
            | 
           2274 | 
               if (res == SZ_OK)
  | 
        
        
            | 
            | 
           2275 | 
                 res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen,
  | 
        
        
            | 
            | 
           2276 | 
                     writeEndMark, progress, alloc, allocBig);
  | 
        
        
            | 
            | 
           2277 | 
             }
  | 
        
        
            | 
            | 
           2278 | 
              | 
        
        
            | 
            | 
           2279 | 
             LzmaEnc_Destroy(p, alloc, allocBig);
  | 
        
        
            | 
            | 
           2280 | 
             return res;
  | 
        
        
            | 
            | 
           2281 | 
           }
  |