ModelPPM.cs 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915
  1. using System;
  2. using System.IO;
  3. using System.Text;
  4. using SharpCompress.Compressors.Rar;
  5. using Decoder = SharpCompress.Compressors.LZMA.RangeCoder.Decoder;
  6. namespace SharpCompress.Compressors.PPMd.H
  7. {
  8. internal class ModelPpm
  9. {
  10. private void InitBlock()
  11. {
  12. for (int i = 0; i < 25; i++)
  13. {
  14. _see2Cont[i] = new See2Context[16];
  15. }
  16. for (int i2 = 0; i2 < 128; i2++)
  17. {
  18. _binSumm[i2] = new int[64];
  19. }
  20. }
  21. public SubAllocator SubAlloc { get; } = new SubAllocator();
  22. public virtual See2Context DummySee2Cont => _dummySee2Cont;
  23. public virtual int InitRl => _initRl;
  24. public virtual int EscCount { get => _escCount; set => _escCount = value & 0xff; }
  25. public virtual int[] CharMask => _charMask;
  26. public virtual int NumMasked { get => _numMasked; set => _numMasked = value; }
  27. public virtual int PrevSuccess { get => _prevSuccess; set => _prevSuccess = value & 0xff; }
  28. public virtual int InitEsc { get => _initEsc; set => _initEsc = value; }
  29. public virtual int RunLength { get => _runLength; set => _runLength = value; }
  30. public virtual int HiBitsFlag { get => _hiBitsFlag; set => _hiBitsFlag = value & 0xff; }
  31. public virtual int[][] BinSumm => _binSumm;
  32. internal RangeCoder Coder { get; private set; }
  33. internal State FoundState { get; private set; }
  34. public virtual byte[] Heap => SubAlloc.Heap;
  35. public virtual int OrderFall => _orderFall;
  36. public const int MAX_O = 64; /* maximum allowed model order */
  37. public const int INT_BITS = 7;
  38. public const int PERIOD_BITS = 7;
  39. //UPGRADE_NOTE: Final was removed from the declaration of 'TOT_BITS '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
  40. public static readonly int TOT_BITS = INT_BITS + PERIOD_BITS;
  41. //UPGRADE_NOTE: Final was removed from the declaration of 'INTERVAL '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
  42. public static readonly int INTERVAL = 1 << INT_BITS;
  43. //UPGRADE_NOTE: Final was removed from the declaration of 'BIN_SCALE '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
  44. public static readonly int BIN_SCALE = 1 << TOT_BITS;
  45. public const int MAX_FREQ = 124;
  46. private readonly See2Context[][] _see2Cont = new See2Context[25][];
  47. private See2Context _dummySee2Cont;
  48. private PpmContext _minContext; //medContext
  49. private PpmContext _maxContext;
  50. private int _numMasked, _initEsc, _orderFall, _maxOrder, _runLength, _initRl;
  51. private readonly int[] _charMask = new int[256];
  52. private readonly int[] _ns2Indx = new int[256];
  53. private readonly int[] _ns2BsIndx = new int[256];
  54. private readonly int[] _hb2Flag = new int[256];
  55. // byte EscCount, PrevSuccess, HiBitsFlag;
  56. private int _escCount, _prevSuccess, _hiBitsFlag;
  57. private readonly int[][] _binSumm = new int[128][]; // binary SEE-contexts
  58. private static readonly int[] INIT_BIN_ESC = {0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051};
  59. // Temp fields
  60. //UPGRADE_NOTE: Final was removed from the declaration of 'tempState1 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
  61. private readonly State _tempState1 = new State(null);
  62. //UPGRADE_NOTE: Final was removed from the declaration of 'tempState2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
  63. private readonly State _tempState2 = new State(null);
  64. //UPGRADE_NOTE: Final was removed from the declaration of 'tempState3 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
  65. private readonly State _tempState3 = new State(null);
  66. //UPGRADE_NOTE: Final was removed from the declaration of 'tempState4 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
  67. private readonly State _tempState4 = new State(null);
  68. //UPGRADE_NOTE: Final was removed from the declaration of 'tempStateRef1 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
  69. private readonly StateRef _tempStateRef1 = new StateRef();
  70. //UPGRADE_NOTE: Final was removed from the declaration of 'tempStateRef2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
  71. private readonly StateRef _tempStateRef2 = new StateRef();
  72. //UPGRADE_NOTE: Final was removed from the declaration of 'tempPPMContext1 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
  73. private readonly PpmContext _tempPpmContext1 = new PpmContext(null);
  74. //UPGRADE_NOTE: Final was removed from the declaration of 'tempPPMContext2 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
  75. private readonly PpmContext _tempPpmContext2 = new PpmContext(null);
  76. //UPGRADE_NOTE: Final was removed from the declaration of 'tempPPMContext3 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
  77. private readonly PpmContext _tempPpmContext3 = new PpmContext(null);
  78. //UPGRADE_NOTE: Final was removed from the declaration of 'tempPPMContext4 '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
  79. private readonly PpmContext _tempPpmContext4 = new PpmContext(null);
  80. //UPGRADE_NOTE: Final was removed from the declaration of 'ps '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
  81. private readonly int[] _ps = new int[MAX_O];
  82. public ModelPpm()
  83. {
  84. InitBlock();
  85. _minContext = null;
  86. _maxContext = null;
  87. //medContext = null;
  88. }
  89. private void RestartModelRare()
  90. {
  91. Utility.Fill(_charMask, 0);
  92. SubAlloc.InitSubAllocator();
  93. _initRl = -(_maxOrder < 12 ? _maxOrder : 12) - 1;
  94. int addr = SubAlloc.AllocContext();
  95. _minContext.Address = addr;
  96. _maxContext.Address = addr;
  97. _minContext.SetSuffix(0);
  98. _orderFall = _maxOrder;
  99. _minContext.NumStats = 256;
  100. _minContext.FreqData.SummFreq = _minContext.NumStats + 1;
  101. addr = SubAlloc.AllocUnits(256 / 2);
  102. FoundState.Address = addr;
  103. _minContext.FreqData.SetStats(addr);
  104. State state = new State(SubAlloc.Heap);
  105. addr = _minContext.FreqData.GetStats();
  106. _runLength = _initRl;
  107. _prevSuccess = 0;
  108. for (int i = 0; i < 256; i++)
  109. {
  110. state.Address = addr + i * State.SIZE;
  111. state.Symbol = i;
  112. state.Freq = 1;
  113. state.SetSuccessor(0);
  114. }
  115. for (int i = 0; i < 128; i++)
  116. {
  117. for (int k = 0; k < 8; k++)
  118. {
  119. for (int m = 0; m < 64; m += 8)
  120. {
  121. _binSumm[i][k + m] = BIN_SCALE - INIT_BIN_ESC[k] / (i + 2);
  122. }
  123. }
  124. }
  125. for (int i = 0; i < 25; i++)
  126. {
  127. for (int k = 0; k < 16; k++)
  128. {
  129. _see2Cont[i][k].Initialize(5 * i + 10);
  130. }
  131. }
  132. }
  133. private void StartModelRare(int maxOrder)
  134. {
  135. int i, k, m, step;
  136. _escCount = 1;
  137. _maxOrder = maxOrder;
  138. RestartModelRare();
  139. // Bug Fixed
  140. _ns2BsIndx[0] = 0;
  141. _ns2BsIndx[1] = 2;
  142. for (int j = 0; j < 9; j++)
  143. {
  144. _ns2BsIndx[2 + j] = 4;
  145. }
  146. for (int j = 0; j < 256 - 11; j++)
  147. {
  148. _ns2BsIndx[11 + j] = 6;
  149. }
  150. for (i = 0; i < 3; i++)
  151. {
  152. _ns2Indx[i] = i;
  153. }
  154. for (m = i, k = 1, step = 1; i < 256; i++)
  155. {
  156. _ns2Indx[i] = m;
  157. if ((--k) == 0)
  158. {
  159. k = ++step;
  160. m++;
  161. }
  162. }
  163. for (int j = 0; j < 0x40; j++)
  164. {
  165. _hb2Flag[j] = 0;
  166. }
  167. for (int j = 0; j < 0x100 - 0x40; j++)
  168. {
  169. _hb2Flag[0x40 + j] = 0x08;
  170. }
  171. _dummySee2Cont.Shift = PERIOD_BITS;
  172. }
  173. private void ClearMask()
  174. {
  175. _escCount = 1;
  176. Utility.Fill(_charMask, 0);
  177. }
  178. internal bool DecodeInit(IRarUnpack unpackRead, int escChar)
  179. {
  180. int maxOrder = unpackRead.Char & 0xff;
  181. bool reset = ((maxOrder & 0x20) != 0);
  182. int maxMb = 0;
  183. if (reset)
  184. {
  185. maxMb = unpackRead.Char;
  186. }
  187. else
  188. {
  189. if (SubAlloc.GetAllocatedMemory() == 0)
  190. {
  191. return (false);
  192. }
  193. }
  194. if ((maxOrder & 0x40) != 0)
  195. {
  196. escChar = unpackRead.Char;
  197. unpackRead.PpmEscChar = escChar;
  198. }
  199. Coder = new RangeCoder(unpackRead);
  200. if (reset)
  201. {
  202. maxOrder = (maxOrder & 0x1f) + 1;
  203. if (maxOrder > 16)
  204. {
  205. maxOrder = 16 + (maxOrder - 16) * 3;
  206. }
  207. if (maxOrder == 1)
  208. {
  209. SubAlloc.StopSubAllocator();
  210. return (false);
  211. }
  212. SubAlloc.StartSubAllocator((maxMb + 1) << 20);
  213. _minContext = new PpmContext(Heap);
  214. //medContext = new PPMContext(Heap);
  215. _maxContext = new PpmContext(Heap);
  216. FoundState = new State(Heap);
  217. _dummySee2Cont = new See2Context();
  218. for (int i = 0; i < 25; i++)
  219. {
  220. for (int j = 0; j < 16; j++)
  221. {
  222. _see2Cont[i][j] = new See2Context();
  223. }
  224. }
  225. StartModelRare(maxOrder);
  226. }
  227. return (_minContext.Address != 0);
  228. }
  229. public virtual int DecodeChar()
  230. {
  231. // Debug
  232. //subAlloc.dumpHeap();
  233. if (_minContext.Address <= SubAlloc.PText || _minContext.Address > SubAlloc.HeapEnd)
  234. {
  235. return (-1);
  236. }
  237. if (_minContext.NumStats != 1)
  238. {
  239. if (_minContext.FreqData.GetStats() <= SubAlloc.PText ||
  240. _minContext.FreqData.GetStats() > SubAlloc.HeapEnd)
  241. {
  242. return (-1);
  243. }
  244. if (!_minContext.DecodeSymbol1(this))
  245. {
  246. return (-1);
  247. }
  248. }
  249. else
  250. {
  251. _minContext.DecodeBinSymbol(this);
  252. }
  253. Coder.Decode();
  254. while (FoundState.Address == 0)
  255. {
  256. Coder.AriDecNormalize();
  257. do
  258. {
  259. _orderFall++;
  260. _minContext.Address = _minContext.GetSuffix(); // =MinContext->Suffix;
  261. if (_minContext.Address <= SubAlloc.PText || _minContext.Address > SubAlloc.HeapEnd)
  262. {
  263. return (-1);
  264. }
  265. }
  266. while (_minContext.NumStats == _numMasked);
  267. if (!_minContext.DecodeSymbol2(this))
  268. {
  269. return (-1);
  270. }
  271. Coder.Decode();
  272. }
  273. int symbol = FoundState.Symbol;
  274. if ((_orderFall == 0) && FoundState.GetSuccessor() > SubAlloc.PText)
  275. {
  276. // MinContext=MaxContext=FoundState->Successor;
  277. int addr = FoundState.GetSuccessor();
  278. _minContext.Address = addr;
  279. _maxContext.Address = addr;
  280. }
  281. else
  282. {
  283. UpdateModel();
  284. //this.foundState.Address=foundState.Address);//TODO just 4 debugging
  285. if (_escCount == 0)
  286. {
  287. ClearMask();
  288. }
  289. }
  290. Coder.AriDecNormalize(); // ARI_DEC_NORMALIZE(Coder.code,Coder.low,Coder.range,Coder.UnpackRead);
  291. return (symbol);
  292. }
  293. public virtual See2Context[][] GetSee2Cont()
  294. {
  295. return _see2Cont;
  296. }
  297. public virtual void IncEscCount(int dEscCount)
  298. {
  299. EscCount = EscCount + dEscCount;
  300. }
  301. public virtual void IncRunLength(int dRunLength)
  302. {
  303. RunLength = RunLength + dRunLength;
  304. }
  305. public virtual int[] GetHb2Flag()
  306. {
  307. return _hb2Flag;
  308. }
  309. public virtual int[] GetNs2BsIndx()
  310. {
  311. return _ns2BsIndx;
  312. }
  313. public virtual int[] GetNs2Indx()
  314. {
  315. return _ns2Indx;
  316. }
  317. private int CreateSuccessors(bool skip, State p1)
  318. {
  319. //State upState = tempState1.Initialize(null);
  320. StateRef upState = _tempStateRef2;
  321. State tempState = _tempState1.Initialize(Heap);
  322. // PPM_CONTEXT* pc=MinContext, * UpBranch=FoundState->Successor;
  323. PpmContext pc = _tempPpmContext1.Initialize(Heap);
  324. pc.Address = _minContext.Address;
  325. PpmContext upBranch = _tempPpmContext2.Initialize(Heap);
  326. upBranch.Address = FoundState.GetSuccessor();
  327. // STATE * p, * ps[MAX_O], ** pps=ps;
  328. State p = _tempState2.Initialize(Heap);
  329. int pps = 0;
  330. bool noLoop = false;
  331. if (!skip)
  332. {
  333. _ps[pps++] = FoundState.Address; // *pps++ = FoundState;
  334. if (pc.GetSuffix() == 0)
  335. {
  336. noLoop = true;
  337. }
  338. }
  339. if (!noLoop)
  340. {
  341. bool loopEntry = false;
  342. if (p1.Address != 0)
  343. {
  344. p.Address = p1.Address;
  345. pc.Address = pc.GetSuffix(); // =pc->Suffix;
  346. loopEntry = true;
  347. }
  348. do
  349. {
  350. if (!loopEntry)
  351. {
  352. pc.Address = pc.GetSuffix(); // pc=pc->Suffix;
  353. if (pc.NumStats != 1)
  354. {
  355. p.Address = pc.FreqData.GetStats(); // p=pc->U.Stats
  356. if (p.Symbol != FoundState.Symbol)
  357. {
  358. do
  359. {
  360. p.IncrementAddress();
  361. }
  362. while (p.Symbol != FoundState.Symbol);
  363. }
  364. }
  365. else
  366. {
  367. p.Address = pc.GetOneState().Address; // p=&(pc->OneState);
  368. }
  369. } // LOOP_ENTRY:
  370. loopEntry = false;
  371. if (p.GetSuccessor() != upBranch.Address)
  372. {
  373. pc.Address = p.GetSuccessor(); // =p->Successor;
  374. break;
  375. }
  376. _ps[pps++] = p.Address;
  377. }
  378. while (pc.GetSuffix() != 0);
  379. } // NO_LOOP:
  380. if (pps == 0)
  381. {
  382. return pc.Address;
  383. }
  384. upState.Symbol = Heap[upBranch.Address]; // UpState.Symbol=*(byte*)
  385. // UpBranch;
  386. // UpState.Successor=(PPM_CONTEXT*) (((byte*) UpBranch)+1);
  387. upState.SetSuccessor(upBranch.Address + 1); //TODO check if +1 necessary
  388. if (pc.NumStats != 1)
  389. {
  390. if (pc.Address <= SubAlloc.PText)
  391. {
  392. return (0);
  393. }
  394. p.Address = pc.FreqData.GetStats();
  395. if (p.Symbol != upState.Symbol)
  396. {
  397. do
  398. {
  399. p.IncrementAddress();
  400. }
  401. while (p.Symbol != upState.Symbol);
  402. }
  403. int cf = p.Freq - 1;
  404. int s0 = pc.FreqData.SummFreq - pc.NumStats - cf;
  405. // UpState.Freq=1+((2*cf <= s0)?(5*cf > s0):((2*cf+3*s0-1)/(2*s0)));
  406. upState.Freq = 1 + ((2 * cf <= s0) ? (5 * cf > s0 ? 1 : 0) : ((2 * cf + 3 * s0 - 1) / (2 * s0)));
  407. }
  408. else
  409. {
  410. upState.Freq = pc.GetOneState().Freq; // UpState.Freq=pc->OneState.Freq;
  411. }
  412. do
  413. {
  414. // pc = pc->createChild(this,*--pps,UpState);
  415. tempState.Address = _ps[--pps];
  416. pc.Address = pc.CreateChild(this, tempState, upState);
  417. if (pc.Address == 0)
  418. {
  419. return 0;
  420. }
  421. }
  422. while (pps != 0);
  423. return pc.Address;
  424. }
  425. private void UpdateModelRestart()
  426. {
  427. RestartModelRare();
  428. _escCount = 0;
  429. }
  430. private void UpdateModel()
  431. {
  432. //System.out.println("ModelPPM.updateModel()");
  433. // STATE fs = *FoundState, *p = NULL;
  434. StateRef fs = _tempStateRef1;
  435. fs.Values = FoundState;
  436. State p = _tempState3.Initialize(Heap);
  437. State tempState = _tempState4.Initialize(Heap);
  438. PpmContext pc = _tempPpmContext3.Initialize(Heap);
  439. PpmContext successor = _tempPpmContext4.Initialize(Heap);
  440. int ns1, ns, cf, sf, s0;
  441. pc.Address = _minContext.GetSuffix();
  442. if (fs.Freq < MAX_FREQ / 4 && pc.Address != 0)
  443. {
  444. if (pc.NumStats != 1)
  445. {
  446. p.Address = pc.FreqData.GetStats();
  447. if (p.Symbol != fs.Symbol)
  448. {
  449. do
  450. {
  451. p.IncrementAddress();
  452. }
  453. while (p.Symbol != fs.Symbol);
  454. tempState.Address = p.Address - State.SIZE;
  455. if (p.Freq >= tempState.Freq)
  456. {
  457. State.PpmdSwap(p, tempState);
  458. p.DecrementAddress();
  459. }
  460. }
  461. if (p.Freq < MAX_FREQ - 9)
  462. {
  463. p.IncrementFreq(2);
  464. pc.FreqData.IncrementSummFreq(2);
  465. }
  466. }
  467. else
  468. {
  469. p.Address = pc.GetOneState().Address;
  470. if (p.Freq < 32)
  471. {
  472. p.IncrementFreq(1);
  473. }
  474. }
  475. }
  476. if (_orderFall == 0)
  477. {
  478. FoundState.SetSuccessor(CreateSuccessors(true, p));
  479. _minContext.Address = FoundState.GetSuccessor();
  480. _maxContext.Address = FoundState.GetSuccessor();
  481. if (_minContext.Address == 0)
  482. {
  483. UpdateModelRestart();
  484. return;
  485. }
  486. return;
  487. }
  488. SubAlloc.Heap[SubAlloc.PText] = (byte)fs.Symbol;
  489. SubAlloc.IncPText();
  490. successor.Address = SubAlloc.PText;
  491. if (SubAlloc.PText >= SubAlloc.FakeUnitsStart)
  492. {
  493. UpdateModelRestart();
  494. return;
  495. }
  496. // // Debug
  497. // subAlloc.dumpHeap();
  498. if (fs.GetSuccessor() != 0)
  499. {
  500. if (fs.GetSuccessor() <= SubAlloc.PText)
  501. {
  502. fs.SetSuccessor(CreateSuccessors(false, p));
  503. if (fs.GetSuccessor() == 0)
  504. {
  505. UpdateModelRestart();
  506. return;
  507. }
  508. }
  509. if (--_orderFall == 0)
  510. {
  511. successor.Address = fs.GetSuccessor();
  512. if (_maxContext.Address != _minContext.Address)
  513. {
  514. SubAlloc.DecPText(1);
  515. }
  516. }
  517. }
  518. else
  519. {
  520. FoundState.SetSuccessor(successor.Address);
  521. fs.SetSuccessor(_minContext);
  522. }
  523. // // Debug
  524. // subAlloc.dumpHeap();
  525. ns = _minContext.NumStats;
  526. s0 = _minContext.FreqData.SummFreq - (ns) - (fs.Freq - 1);
  527. for (pc.Address = _maxContext.Address; pc.Address != _minContext.Address; pc.Address = pc.GetSuffix())
  528. {
  529. if ((ns1 = pc.NumStats) != 1)
  530. {
  531. if ((ns1 & 1) == 0)
  532. {
  533. //System.out.println(ns1);
  534. pc.FreqData.SetStats(SubAlloc.ExpandUnits(pc.FreqData.GetStats(), Utility.URShift(ns1, 1)));
  535. if (pc.FreqData.GetStats() == 0)
  536. {
  537. UpdateModelRestart();
  538. return;
  539. }
  540. }
  541. // bug fixed
  542. // int sum = ((2 * ns1 < ns) ? 1 : 0) +
  543. // 2 * ((4 * ((ns1 <= ns) ? 1 : 0)) & ((pc.getFreqData()
  544. // .getSummFreq() <= 8 * ns1) ? 1 : 0));
  545. int sum = ((2 * ns1 < ns) ? 1 : 0) +
  546. 2 * (((4 * ns1 <= ns) ? 1 : 0) & ((pc.FreqData.SummFreq <= 8 * ns1) ? 1 : 0));
  547. pc.FreqData.IncrementSummFreq(sum);
  548. }
  549. else
  550. {
  551. p.Address = SubAlloc.AllocUnits(1);
  552. if (p.Address == 0)
  553. {
  554. UpdateModelRestart();
  555. return;
  556. }
  557. p.SetValues(pc.GetOneState());
  558. pc.FreqData.SetStats(p);
  559. if (p.Freq < MAX_FREQ / 4 - 1)
  560. {
  561. p.IncrementFreq(p.Freq);
  562. }
  563. else
  564. {
  565. p.Freq = MAX_FREQ - 4;
  566. }
  567. pc.FreqData.SummFreq = (p.Freq + _initEsc + (ns > 3 ? 1 : 0));
  568. }
  569. cf = 2 * fs.Freq * (pc.FreqData.SummFreq + 6);
  570. sf = s0 + pc.FreqData.SummFreq;
  571. if (cf < 6 * sf)
  572. {
  573. cf = 1 + (cf > sf ? 1 : 0) + (cf >= 4 * sf ? 1 : 0);
  574. pc.FreqData.IncrementSummFreq(3);
  575. }
  576. else
  577. {
  578. cf = 4 + (cf >= 9 * sf ? 1 : 0) + (cf >= 12 * sf ? 1 : 0) + (cf >= 15 * sf ? 1 : 0);
  579. pc.FreqData.IncrementSummFreq(cf);
  580. }
  581. p.Address = pc.FreqData.GetStats() + ns1 * State.SIZE;
  582. p.SetSuccessor(successor);
  583. p.Symbol = fs.Symbol;
  584. p.Freq = cf;
  585. pc.NumStats = ++ns1;
  586. }
  587. int address = fs.GetSuccessor();
  588. _maxContext.Address = address;
  589. _minContext.Address = address;
  590. //TODO-----debug
  591. // int pos = minContext.getFreqData().getStats();
  592. // State a = new State(getHeap());
  593. // a.Address=pos);
  594. // pos+=State.size;
  595. // a.Address=pos);
  596. //--dbg end
  597. }
  598. // Debug
  599. public override String ToString()
  600. {
  601. StringBuilder buffer = new StringBuilder();
  602. buffer.Append("ModelPPM[");
  603. buffer.Append("\n numMasked=");
  604. buffer.Append(_numMasked);
  605. buffer.Append("\n initEsc=");
  606. buffer.Append(_initEsc);
  607. buffer.Append("\n orderFall=");
  608. buffer.Append(_orderFall);
  609. buffer.Append("\n maxOrder=");
  610. buffer.Append(_maxOrder);
  611. buffer.Append("\n runLength=");
  612. buffer.Append(_runLength);
  613. buffer.Append("\n initRL=");
  614. buffer.Append(_initRl);
  615. buffer.Append("\n escCount=");
  616. buffer.Append(_escCount);
  617. buffer.Append("\n prevSuccess=");
  618. buffer.Append(_prevSuccess);
  619. buffer.Append("\n foundState=");
  620. buffer.Append(FoundState);
  621. buffer.Append("\n coder=");
  622. buffer.Append(Coder);
  623. buffer.Append("\n subAlloc=");
  624. buffer.Append(SubAlloc);
  625. buffer.Append("\n]");
  626. return buffer.ToString();
  627. }
  628. // Debug
  629. // public void dumpHeap() {
  630. // subAlloc.dumpHeap();
  631. // }
  632. internal bool DecodeInit(Stream stream, int maxOrder, int maxMemory)
  633. {
  634. if (stream != null)
  635. {
  636. Coder = new RangeCoder(stream);
  637. }
  638. if (maxOrder == 1)
  639. {
  640. SubAlloc.StopSubAllocator();
  641. return (false);
  642. }
  643. SubAlloc.StartSubAllocator(maxMemory);
  644. _minContext = new PpmContext(Heap);
  645. //medContext = new PPMContext(Heap);
  646. _maxContext = new PpmContext(Heap);
  647. FoundState = new State(Heap);
  648. _dummySee2Cont = new See2Context();
  649. for (int i = 0; i < 25; i++)
  650. {
  651. for (int j = 0; j < 16; j++)
  652. {
  653. _see2Cont[i][j] = new See2Context();
  654. }
  655. }
  656. StartModelRare(maxOrder);
  657. return (_minContext.Address != 0);
  658. }
  659. internal void NextContext()
  660. {
  661. int addr = FoundState.GetSuccessor();
  662. if (_orderFall == 0 && addr > SubAlloc.PText)
  663. {
  664. _minContext.Address = addr;
  665. _maxContext.Address = addr;
  666. }
  667. else
  668. {
  669. UpdateModel();
  670. }
  671. }
  672. public int DecodeChar(Decoder decoder)
  673. {
  674. if (_minContext.NumStats != 1)
  675. {
  676. State s = _tempState1.Initialize(Heap);
  677. s.Address = _minContext.FreqData.GetStats();
  678. int i;
  679. int count, hiCnt;
  680. if ((count = (int)decoder.GetThreshold((uint)_minContext.FreqData.SummFreq)) < (hiCnt = s.Freq))
  681. {
  682. byte symbol;
  683. decoder.Decode(0, (uint)s.Freq);
  684. symbol = (byte)s.Symbol;
  685. _minContext.update1_0(this, s.Address);
  686. NextContext();
  687. return symbol;
  688. }
  689. _prevSuccess = 0;
  690. i = _minContext.NumStats - 1;
  691. do
  692. {
  693. s.IncrementAddress();
  694. if ((hiCnt += s.Freq) > count)
  695. {
  696. byte symbol;
  697. decoder.Decode((uint)(hiCnt - s.Freq), (uint)s.Freq);
  698. symbol = (byte)s.Symbol;
  699. _minContext.Update1(this, s.Address);
  700. NextContext();
  701. return symbol;
  702. }
  703. }
  704. while (--i > 0);
  705. if (count >= _minContext.FreqData.SummFreq)
  706. {
  707. return -2;
  708. }
  709. _hiBitsFlag = _hb2Flag[FoundState.Symbol];
  710. decoder.Decode((uint)hiCnt, (uint)(_minContext.FreqData.SummFreq - hiCnt));
  711. for (i = 0; i < 256; i++)
  712. {
  713. _charMask[i] = -1;
  714. }
  715. _charMask[s.Symbol] = 0;
  716. i = _minContext.NumStats - 1;
  717. do
  718. {
  719. s.DecrementAddress();
  720. _charMask[s.Symbol] = 0;
  721. }
  722. while (--i > 0);
  723. }
  724. else
  725. {
  726. State rs = _tempState1.Initialize(Heap);
  727. rs.Address = _minContext.GetOneState().Address;
  728. _hiBitsFlag = GetHb2Flag()[FoundState.Symbol];
  729. int off1 = rs.Freq - 1;
  730. int off2 = _minContext.GetArrayIndex(this, rs);
  731. int bs = _binSumm[off1][off2];
  732. if (decoder.DecodeBit((uint)bs, 14) == 0)
  733. {
  734. byte symbol;
  735. _binSumm[off1][off2] = (bs + INTERVAL - _minContext.GetMean(bs, PERIOD_BITS, 2)) & 0xFFFF;
  736. FoundState.Address = rs.Address;
  737. symbol = (byte)rs.Symbol;
  738. rs.IncrementFreq((rs.Freq < 128) ? 1 : 0);
  739. _prevSuccess = 1;
  740. IncRunLength(1);
  741. NextContext();
  742. return symbol;
  743. }
  744. bs = (bs - _minContext.GetMean(bs, PERIOD_BITS, 2)) & 0xFFFF;
  745. _binSumm[off1][off2] = bs;
  746. _initEsc = PpmContext.EXP_ESCAPE[Utility.URShift(bs, 10)];
  747. int i;
  748. for (i = 0; i < 256; i++)
  749. {
  750. _charMask[i] = -1;
  751. }
  752. _charMask[rs.Symbol] = 0;
  753. _prevSuccess = 0;
  754. }
  755. for (;;)
  756. {
  757. State s = _tempState1.Initialize(Heap);
  758. int i;
  759. int freqSum, count, hiCnt;
  760. See2Context see;
  761. int num, numMasked = _minContext.NumStats;
  762. do
  763. {
  764. _orderFall++;
  765. _minContext.Address = _minContext.GetSuffix();
  766. if (_minContext.Address <= SubAlloc.PText || _minContext.Address > SubAlloc.HeapEnd)
  767. {
  768. return -1;
  769. }
  770. }
  771. while (_minContext.NumStats == numMasked);
  772. hiCnt = 0;
  773. s.Address = _minContext.FreqData.GetStats();
  774. i = 0;
  775. num = _minContext.NumStats - numMasked;
  776. do
  777. {
  778. int k = _charMask[s.Symbol];
  779. hiCnt += s.Freq & k;
  780. _minContext._ps[i] = s.Address;
  781. s.IncrementAddress();
  782. i -= k;
  783. }
  784. while (i != num);
  785. see = _minContext.MakeEscFreq(this, numMasked, out freqSum);
  786. freqSum += hiCnt;
  787. count = (int)decoder.GetThreshold((uint)freqSum);
  788. if (count < hiCnt)
  789. {
  790. byte symbol;
  791. State ps = _tempState2.Initialize(Heap);
  792. for (hiCnt = 0, i = 0, ps.Address = _minContext._ps[i];
  793. (hiCnt += ps.Freq) <= count;
  794. i++, ps.Address = _minContext._ps[i])
  795. {
  796. ;
  797. }
  798. s.Address = ps.Address;
  799. decoder.Decode((uint)(hiCnt - s.Freq), (uint)s.Freq);
  800. see.Update();
  801. symbol = (byte)s.Symbol;
  802. _minContext.Update2(this, s.Address);
  803. UpdateModel();
  804. return symbol;
  805. }
  806. if (count >= freqSum)
  807. {
  808. return -2;
  809. }
  810. decoder.Decode((uint)hiCnt, (uint)(freqSum - hiCnt));
  811. see.Summ = see.Summ + freqSum;
  812. do
  813. {
  814. s.Address = _minContext._ps[--i];
  815. _charMask[s.Symbol] = 0;
  816. }
  817. while (i != 0);
  818. }
  819. }
  820. }
  821. }