model.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639
  1. /****************************************************************************
  2. * This file is part of PPMd project *
  3. * Written and distributed to public domain by Dmitry Shkarin 1997, *
  4. * 1999-2000 *
  5. * Contents: model description and encoding/decoding routines *
  6. ****************************************************************************/
  7. static const int MAX_O=64; /* maximum allowed model order */
  8. const uint TOP=1 << 24, BOT=1 << 15;
  9. template <class T>
  10. inline void _PPMD_SWAP(T& t1,T& t2) { T tmp=t1; t1=t2; t2=tmp; }
  11. inline RARPPM_CONTEXT* RARPPM_CONTEXT::createChild(ModelPPM *Model,RARPPM_STATE* pStats,
  12. RARPPM_STATE& FirstState)
  13. {
  14. RARPPM_CONTEXT* pc = (RARPPM_CONTEXT*) Model->SubAlloc.AllocContext();
  15. if ( pc )
  16. {
  17. pc->NumStats=1;
  18. pc->OneState=FirstState;
  19. pc->Suffix=this;
  20. pStats->Successor=pc;
  21. }
  22. return pc;
  23. }
  24. ModelPPM::ModelPPM()
  25. {
  26. MinContext=NULL;
  27. MaxContext=NULL;
  28. MedContext=NULL;
  29. }
  30. void ModelPPM::RestartModelRare()
  31. {
  32. int i, k, m;
  33. memset(CharMask,0,sizeof(CharMask));
  34. SubAlloc.InitSubAllocator();
  35. InitRL=-(MaxOrder < 12 ? MaxOrder:12)-1;
  36. MinContext = MaxContext = (RARPPM_CONTEXT*) SubAlloc.AllocContext();
  37. if (MinContext == NULL)
  38. throw std::bad_alloc();
  39. MinContext->Suffix=NULL;
  40. OrderFall=MaxOrder;
  41. MinContext->U.SummFreq=(MinContext->NumStats=256)+1;
  42. FoundState=MinContext->U.Stats=(RARPPM_STATE*)SubAlloc.AllocUnits(256/2);
  43. if (FoundState == NULL)
  44. throw std::bad_alloc();
  45. for (RunLength=InitRL, PrevSuccess=i=0;i < 256;i++)
  46. {
  47. MinContext->U.Stats[i].Symbol=i;
  48. MinContext->U.Stats[i].Freq=1;
  49. MinContext->U.Stats[i].Successor=NULL;
  50. }
  51. static const ushort InitBinEsc[]={
  52. 0x3CDD,0x1F3F,0x59BF,0x48F3,0x64A1,0x5ABC,0x6632,0x6051
  53. };
  54. for (i=0;i < 128;i++)
  55. for (k=0;k < 8;k++)
  56. for (m=0;m < 64;m += 8)
  57. BinSumm[i][k+m]=BIN_SCALE-InitBinEsc[k]/(i+2);
  58. for (i=0;i < 25;i++)
  59. for (k=0;k < 16;k++)
  60. SEE2Cont[i][k].init(5*i+10);
  61. }
  62. void ModelPPM::StartModelRare(int MaxOrder)
  63. {
  64. int i, k, m ,Step;
  65. EscCount=1;
  66. /*
  67. if (MaxOrder < 2)
  68. {
  69. memset(CharMask,0,sizeof(CharMask));
  70. OrderFall=ModelPPM::MaxOrder;
  71. MinContext=MaxContext;
  72. while (MinContext->Suffix != NULL)
  73. {
  74. MinContext=MinContext->Suffix;
  75. OrderFall--;
  76. }
  77. FoundState=MinContext->U.Stats;
  78. MinContext=MaxContext;
  79. }
  80. else
  81. */
  82. {
  83. ModelPPM::MaxOrder=MaxOrder;
  84. RestartModelRare();
  85. NS2BSIndx[0]=2*0;
  86. NS2BSIndx[1]=2*1;
  87. memset(NS2BSIndx+2,2*2,9);
  88. memset(NS2BSIndx+11,2*3,256-11);
  89. for (i=0;i < 3;i++)
  90. NS2Indx[i]=i;
  91. for (m=i, k=Step=1;i < 256;i++)
  92. {
  93. NS2Indx[i]=m;
  94. if ( !--k )
  95. {
  96. k = ++Step;
  97. m++;
  98. }
  99. }
  100. memset(HB2Flag,0,0x40);
  101. memset(HB2Flag+0x40,0x08,0x100-0x40);
  102. DummySEE2Cont.Shift=PERIOD_BITS;
  103. }
  104. }
  105. void RARPPM_CONTEXT::rescale(ModelPPM *Model)
  106. {
  107. int OldNS=NumStats, i=NumStats-1, Adder, EscFreq;
  108. RARPPM_STATE* p1, * p;
  109. for (p=Model->FoundState;p != U.Stats;p--)
  110. _PPMD_SWAP(p[0],p[-1]);
  111. U.Stats->Freq += 4;
  112. U.SummFreq += 4;
  113. EscFreq=U.SummFreq-p->Freq;
  114. Adder=(Model->OrderFall != 0);
  115. U.SummFreq = (p->Freq=(p->Freq+Adder) >> 1);
  116. do
  117. {
  118. EscFreq -= (++p)->Freq;
  119. U.SummFreq += (p->Freq=(p->Freq+Adder) >> 1);
  120. if (p[0].Freq > p[-1].Freq)
  121. {
  122. RARPPM_STATE tmp=*(p1=p);
  123. do
  124. {
  125. p1[0]=p1[-1];
  126. } while (--p1 != U.Stats && tmp.Freq > p1[-1].Freq);
  127. *p1=tmp;
  128. }
  129. } while ( --i );
  130. if (p->Freq == 0)
  131. {
  132. do
  133. {
  134. i++;
  135. } while ((--p)->Freq == 0);
  136. EscFreq += i;
  137. if ((NumStats -= i) == 1)
  138. {
  139. RARPPM_STATE tmp=*U.Stats;
  140. do
  141. {
  142. tmp.Freq-=(tmp.Freq >> 1);
  143. EscFreq>>=1;
  144. } while (EscFreq > 1);
  145. Model->SubAlloc.FreeUnits(U.Stats,(OldNS+1) >> 1);
  146. *(Model->FoundState=&OneState)=tmp; return;
  147. }
  148. }
  149. U.SummFreq += (EscFreq -= (EscFreq >> 1));
  150. int n0=(OldNS+1) >> 1, n1=(NumStats+1) >> 1;
  151. if (n0 != n1)
  152. U.Stats = (RARPPM_STATE*) Model->SubAlloc.ShrinkUnits(U.Stats,n0,n1);
  153. Model->FoundState=U.Stats;
  154. }
  155. inline RARPPM_CONTEXT* ModelPPM::CreateSuccessors(bool Skip,RARPPM_STATE* p1)
  156. {
  157. RARPPM_STATE UpState;
  158. RARPPM_CONTEXT* pc=MinContext, * UpBranch=FoundState->Successor;
  159. RARPPM_STATE * p, * ps[MAX_O], ** pps=ps;
  160. if ( !Skip )
  161. {
  162. *pps++ = FoundState;
  163. if ( !pc->Suffix )
  164. goto NO_LOOP;
  165. }
  166. if ( p1 )
  167. {
  168. p=p1;
  169. pc=pc->Suffix;
  170. goto LOOP_ENTRY;
  171. }
  172. do
  173. {
  174. pc=pc->Suffix;
  175. if (pc->NumStats != 1)
  176. {
  177. if ((p=pc->U.Stats)->Symbol != FoundState->Symbol)
  178. do
  179. {
  180. p++;
  181. } while (p->Symbol != FoundState->Symbol);
  182. }
  183. else
  184. p=&(pc->OneState);
  185. LOOP_ENTRY:
  186. if (p->Successor != UpBranch)
  187. {
  188. pc=p->Successor;
  189. break;
  190. }
  191. // We ensure that PPM order input parameter does not exceed MAX_O (64),
  192. // so we do not really need this check and added it for extra safety.
  193. // See CVE-2017-17969 for details.
  194. if (pps>=ps+ASIZE(ps))
  195. return NULL;
  196. *pps++ = p;
  197. } while ( pc->Suffix );
  198. NO_LOOP:
  199. if (pps == ps)
  200. return pc;
  201. UpState.Symbol=*(byte*) UpBranch;
  202. UpState.Successor=(RARPPM_CONTEXT*) (((byte*) UpBranch)+1);
  203. if (pc->NumStats != 1)
  204. {
  205. if ((byte*) pc <= SubAlloc.pText)
  206. return(NULL);
  207. if ((p=pc->U.Stats)->Symbol != UpState.Symbol)
  208. do
  209. {
  210. p++;
  211. } while (p->Symbol != UpState.Symbol);
  212. uint cf=p->Freq-1;
  213. uint s0=pc->U.SummFreq-pc->NumStats-cf;
  214. UpState.Freq=1+((2*cf <= s0)?(5*cf > s0):((2*cf+3*s0-1)/(2*s0)));
  215. }
  216. else
  217. UpState.Freq=pc->OneState.Freq;
  218. do
  219. {
  220. pc = pc->createChild(this,*--pps,UpState);
  221. if ( !pc )
  222. return NULL;
  223. } while (pps != ps);
  224. return pc;
  225. }
  226. inline void ModelPPM::UpdateModel()
  227. {
  228. RARPPM_STATE fs = *FoundState, *p = NULL;
  229. RARPPM_CONTEXT *pc, *Successor;
  230. uint ns1, ns, cf, sf, s0;
  231. if (fs.Freq < MAX_FREQ/4 && (pc=MinContext->Suffix) != NULL)
  232. {
  233. if (pc->NumStats != 1)
  234. {
  235. if ((p=pc->U.Stats)->Symbol != fs.Symbol)
  236. {
  237. do
  238. {
  239. p++;
  240. } while (p->Symbol != fs.Symbol);
  241. if (p[0].Freq >= p[-1].Freq)
  242. {
  243. _PPMD_SWAP(p[0],p[-1]);
  244. p--;
  245. }
  246. }
  247. if (p->Freq < MAX_FREQ-9)
  248. {
  249. p->Freq += 2;
  250. pc->U.SummFreq += 2;
  251. }
  252. }
  253. else
  254. {
  255. p=&(pc->OneState);
  256. p->Freq += (p->Freq < 32);
  257. }
  258. }
  259. if ( !OrderFall )
  260. {
  261. MinContext=MaxContext=FoundState->Successor=CreateSuccessors(TRUE,p);
  262. if ( !MinContext )
  263. goto RESTART_MODEL;
  264. return;
  265. }
  266. *SubAlloc.pText++ = fs.Symbol;
  267. Successor = (RARPPM_CONTEXT*) SubAlloc.pText;
  268. if (SubAlloc.pText >= SubAlloc.FakeUnitsStart)
  269. goto RESTART_MODEL;
  270. if ( fs.Successor )
  271. {
  272. if ((byte*) fs.Successor <= SubAlloc.pText &&
  273. (fs.Successor=CreateSuccessors(FALSE,p)) == NULL)
  274. goto RESTART_MODEL;
  275. if ( !--OrderFall )
  276. {
  277. Successor=fs.Successor;
  278. SubAlloc.pText -= (MaxContext != MinContext);
  279. }
  280. }
  281. else
  282. {
  283. FoundState->Successor=Successor;
  284. fs.Successor=MinContext;
  285. }
  286. s0=MinContext->U.SummFreq-(ns=MinContext->NumStats)-(fs.Freq-1);
  287. for (pc=MaxContext;pc != MinContext;pc=pc->Suffix)
  288. {
  289. if ((ns1=pc->NumStats) != 1)
  290. {
  291. if ((ns1 & 1) == 0)
  292. {
  293. pc->U.Stats=(RARPPM_STATE*) SubAlloc.ExpandUnits(pc->U.Stats,ns1 >> 1);
  294. if ( !pc->U.Stats )
  295. goto RESTART_MODEL;
  296. }
  297. pc->U.SummFreq += (2*ns1 < ns)+2*((4*ns1 <= ns) & (pc->U.SummFreq <= 8*ns1));
  298. }
  299. else
  300. {
  301. p=(RARPPM_STATE*) SubAlloc.AllocUnits(1);
  302. if ( !p )
  303. goto RESTART_MODEL;
  304. *p=pc->OneState;
  305. pc->U.Stats=p;
  306. if (p->Freq < MAX_FREQ/4-1)
  307. p->Freq += p->Freq;
  308. else
  309. p->Freq = MAX_FREQ-4;
  310. pc->U.SummFreq=p->Freq+InitEsc+(ns > 3);
  311. }
  312. cf=2*fs.Freq*(pc->U.SummFreq+6);
  313. sf=s0+pc->U.SummFreq;
  314. if (cf < 6*sf)
  315. {
  316. cf=1+(cf > sf)+(cf >= 4*sf);
  317. pc->U.SummFreq += 3;
  318. }
  319. else
  320. {
  321. cf=4+(cf >= 9*sf)+(cf >= 12*sf)+(cf >= 15*sf);
  322. pc->U.SummFreq += cf;
  323. }
  324. p=pc->U.Stats+ns1;
  325. p->Successor=Successor;
  326. p->Symbol = fs.Symbol;
  327. p->Freq = cf;
  328. pc->NumStats=++ns1;
  329. }
  330. MaxContext=MinContext=fs.Successor;
  331. return;
  332. RESTART_MODEL:
  333. RestartModelRare();
  334. EscCount=0;
  335. }
  336. // Tabulated escapes for exponential symbol distribution
  337. static const byte ExpEscape[16]={ 25,14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
  338. #define GET_MEAN(SUMM,SHIFT,ROUND) ((SUMM+(1 << (SHIFT-ROUND))) >> (SHIFT))
  339. inline void RARPPM_CONTEXT::decodeBinSymbol(ModelPPM *Model)
  340. {
  341. RARPPM_STATE& rs=OneState;
  342. Model->HiBitsFlag=Model->HB2Flag[Model->FoundState->Symbol];
  343. ushort& bs=Model->BinSumm[rs.Freq-1][Model->PrevSuccess+
  344. Model->NS2BSIndx[Suffix->NumStats-1]+
  345. Model->HiBitsFlag+2*Model->HB2Flag[rs.Symbol]+
  346. ((Model->RunLength >> 26) & 0x20)];
  347. if (Model->Coder.GetCurrentShiftCount(TOT_BITS) < bs)
  348. {
  349. Model->FoundState=&rs;
  350. rs.Freq += (rs.Freq < 128);
  351. Model->Coder.SubRange.LowCount=0;
  352. Model->Coder.SubRange.HighCount=bs;
  353. bs = GET_SHORT16(bs+INTERVAL-GET_MEAN(bs,PERIOD_BITS,2));
  354. Model->PrevSuccess=1;
  355. Model->RunLength++;
  356. }
  357. else
  358. {
  359. Model->Coder.SubRange.LowCount=bs;
  360. bs = GET_SHORT16(bs-GET_MEAN(bs,PERIOD_BITS,2));
  361. Model->Coder.SubRange.HighCount=BIN_SCALE;
  362. Model->InitEsc=ExpEscape[bs >> 10];
  363. Model->NumMasked=1;
  364. Model->CharMask[rs.Symbol]=Model->EscCount;
  365. Model->PrevSuccess=0;
  366. Model->FoundState=NULL;
  367. }
  368. }
  369. inline void RARPPM_CONTEXT::update1(ModelPPM *Model,RARPPM_STATE* p)
  370. {
  371. (Model->FoundState=p)->Freq += 4;
  372. U.SummFreq += 4;
  373. if (p[0].Freq > p[-1].Freq)
  374. {
  375. _PPMD_SWAP(p[0],p[-1]);
  376. Model->FoundState=--p;
  377. if (p->Freq > MAX_FREQ)
  378. rescale(Model);
  379. }
  380. }
  381. inline bool RARPPM_CONTEXT::decodeSymbol1(ModelPPM *Model)
  382. {
  383. Model->Coder.SubRange.scale=U.SummFreq;
  384. RARPPM_STATE* p=U.Stats;
  385. int i, HiCnt;
  386. int count=Model->Coder.GetCurrentCount();
  387. if (count>=(int)Model->Coder.SubRange.scale)
  388. return(false);
  389. if (count < (HiCnt=p->Freq))
  390. {
  391. Model->PrevSuccess=(2*(Model->Coder.SubRange.HighCount=HiCnt) > Model->Coder.SubRange.scale);
  392. Model->RunLength += Model->PrevSuccess;
  393. (Model->FoundState=p)->Freq=(HiCnt += 4);
  394. U.SummFreq += 4;
  395. if (HiCnt > MAX_FREQ)
  396. rescale(Model);
  397. Model->Coder.SubRange.LowCount=0;
  398. return(true);
  399. }
  400. else
  401. if (Model->FoundState==NULL)
  402. return(false);
  403. Model->PrevSuccess=0;
  404. i=NumStats-1;
  405. while ((HiCnt += (++p)->Freq) <= count)
  406. if (--i == 0)
  407. {
  408. Model->HiBitsFlag=Model->HB2Flag[Model->FoundState->Symbol];
  409. Model->Coder.SubRange.LowCount=HiCnt;
  410. Model->CharMask[p->Symbol]=Model->EscCount;
  411. i=(Model->NumMasked=NumStats)-1;
  412. Model->FoundState=NULL;
  413. do
  414. {
  415. Model->CharMask[(--p)->Symbol]=Model->EscCount;
  416. } while ( --i );
  417. Model->Coder.SubRange.HighCount=Model->Coder.SubRange.scale;
  418. return(true);
  419. }
  420. Model->Coder.SubRange.LowCount=(Model->Coder.SubRange.HighCount=HiCnt)-p->Freq;
  421. update1(Model,p);
  422. return(true);
  423. }
  424. inline void RARPPM_CONTEXT::update2(ModelPPM *Model,RARPPM_STATE* p)
  425. {
  426. (Model->FoundState=p)->Freq += 4;
  427. U.SummFreq += 4;
  428. if (p->Freq > MAX_FREQ)
  429. rescale(Model);
  430. Model->EscCount++;
  431. Model->RunLength=Model->InitRL;
  432. }
  433. inline RARPPM_SEE2_CONTEXT* RARPPM_CONTEXT::makeEscFreq2(ModelPPM *Model,int Diff)
  434. {
  435. RARPPM_SEE2_CONTEXT* psee2c;
  436. if (NumStats != 256)
  437. {
  438. psee2c=Model->SEE2Cont[Model->NS2Indx[Diff-1]]+
  439. (Diff < Suffix->NumStats-NumStats)+
  440. 2*(U.SummFreq < 11*NumStats)+4*(Model->NumMasked > Diff)+
  441. Model->HiBitsFlag;
  442. Model->Coder.SubRange.scale=psee2c->getMean();
  443. }
  444. else
  445. {
  446. psee2c=&Model->DummySEE2Cont;
  447. Model->Coder.SubRange.scale=1;
  448. }
  449. return psee2c;
  450. }
  451. inline bool RARPPM_CONTEXT::decodeSymbol2(ModelPPM *Model)
  452. {
  453. int count, HiCnt, i=NumStats-Model->NumMasked;
  454. RARPPM_SEE2_CONTEXT* psee2c=makeEscFreq2(Model,i);
  455. RARPPM_STATE* ps[256], ** pps=ps, * p=U.Stats-1;
  456. HiCnt=0;
  457. do
  458. {
  459. do
  460. {
  461. p++;
  462. } while (Model->CharMask[p->Symbol] == Model->EscCount);
  463. HiCnt += p->Freq;
  464. // We do not reuse PPMd coder in unstable state, so we do not really need
  465. // this check and added it for extra safety. See CVE-2017-17969 for details.
  466. if (pps>=ps+ASIZE(ps))
  467. return false;
  468. *pps++ = p;
  469. } while ( --i );
  470. Model->Coder.SubRange.scale += HiCnt;
  471. count=Model->Coder.GetCurrentCount();
  472. if (count>=(int)Model->Coder.SubRange.scale)
  473. return(false);
  474. p=*(pps=ps);
  475. if (count < HiCnt)
  476. {
  477. HiCnt=0;
  478. while ((HiCnt += p->Freq) <= count)
  479. {
  480. pps++;
  481. if (pps>=ps+ASIZE(ps)) // Extra safety check.
  482. return false;
  483. p=*pps;
  484. }
  485. Model->Coder.SubRange.LowCount = (Model->Coder.SubRange.HighCount=HiCnt)-p->Freq;
  486. psee2c->update();
  487. update2(Model,p);
  488. }
  489. else
  490. {
  491. Model->Coder.SubRange.LowCount=HiCnt;
  492. Model->Coder.SubRange.HighCount=Model->Coder.SubRange.scale;
  493. i=NumStats-Model->NumMasked;
  494. pps--;
  495. do
  496. {
  497. pps++;
  498. if (pps>=ps+ASIZE(ps)) // Extra safety check.
  499. return false;
  500. Model->CharMask[(*pps)->Symbol]=Model->EscCount;
  501. } while ( --i );
  502. psee2c->Summ += Model->Coder.SubRange.scale;
  503. Model->NumMasked = NumStats;
  504. }
  505. return true;
  506. }
  507. inline void ModelPPM::ClearMask()
  508. {
  509. EscCount=1;
  510. memset(CharMask,0,sizeof(CharMask));
  511. }
  512. // reset PPM variables after data error allowing safe resuming
  513. // of further data processing
  514. void ModelPPM::CleanUp()
  515. {
  516. SubAlloc.StopSubAllocator();
  517. SubAlloc.StartSubAllocator(1);
  518. StartModelRare(2);
  519. }
  520. bool ModelPPM::DecodeInit(Unpack *UnpackRead,int &EscChar)
  521. {
  522. int MaxOrder=UnpackRead->GetChar();
  523. bool Reset=(MaxOrder & 0x20)!=0;
  524. int MaxMB;
  525. if (Reset)
  526. MaxMB=UnpackRead->GetChar();
  527. else
  528. if (SubAlloc.GetAllocatedMemory()==0)
  529. return(false);
  530. if (MaxOrder & 0x40)
  531. EscChar=UnpackRead->GetChar();
  532. Coder.InitDecoder(UnpackRead);
  533. if (Reset)
  534. {
  535. MaxOrder=(MaxOrder & 0x1f)+1;
  536. if (MaxOrder>16)
  537. MaxOrder=16+(MaxOrder-16)*3;
  538. if (MaxOrder==1)
  539. {
  540. SubAlloc.StopSubAllocator();
  541. return(false);
  542. }
  543. SubAlloc.StartSubAllocator(MaxMB+1);
  544. StartModelRare(MaxOrder);
  545. }
  546. return(MinContext!=NULL);
  547. }
  548. int ModelPPM::DecodeChar()
  549. {
  550. if ((byte*)MinContext <= SubAlloc.pText || (byte*)MinContext>SubAlloc.HeapEnd)
  551. return(-1);
  552. if (MinContext->NumStats != 1)
  553. {
  554. if ((byte*)MinContext->U.Stats <= SubAlloc.pText || (byte*)MinContext->U.Stats>SubAlloc.HeapEnd)
  555. return(-1);
  556. if (!MinContext->decodeSymbol1(this))
  557. return(-1);
  558. }
  559. else
  560. MinContext->decodeBinSymbol(this);
  561. Coder.Decode();
  562. while ( !FoundState )
  563. {
  564. ARI_DEC_NORMALIZE(Coder.code,Coder.low,Coder.range,Coder.UnpackRead);
  565. do
  566. {
  567. OrderFall++;
  568. MinContext=MinContext->Suffix;
  569. if ((byte*)MinContext <= SubAlloc.pText || (byte*)MinContext>SubAlloc.HeapEnd)
  570. return(-1);
  571. } while (MinContext->NumStats == NumMasked);
  572. if (!MinContext->decodeSymbol2(this))
  573. return(-1);
  574. Coder.Decode();
  575. }
  576. int Symbol=FoundState->Symbol;
  577. if (!OrderFall && (byte*) FoundState->Successor > SubAlloc.pText)
  578. MinContext=MaxContext=FoundState->Successor;
  579. else
  580. {
  581. UpdateModel();
  582. if (EscCount == 0)
  583. ClearMask();
  584. }
  585. ARI_DEC_NORMALIZE(Coder.code,Coder.low,Coder.range,Coder.UnpackRead);
  586. return(Symbol);
  587. }