Subversion Repositories Games.Chess Giants

Rev

Blame | Last modification | View Log | Download | RSS feed

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