model.cpp 15 KB

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