1370b324cSopenharmony_ci/* Ppmd7Dec.c -- Ppmd7z (PPMdH with 7z Range Coder) Decoder 2370b324cSopenharmony_ci2023-04-02 : Igor Pavlov : Public domain 3370b324cSopenharmony_ciThis code is based on: 4370b324cSopenharmony_ci PPMd var.H (2001): Dmitry Shkarin : Public domain */ 5370b324cSopenharmony_ci 6370b324cSopenharmony_ci 7370b324cSopenharmony_ci#include "Precomp.h" 8370b324cSopenharmony_ci 9370b324cSopenharmony_ci#include "Ppmd7.h" 10370b324cSopenharmony_ci 11370b324cSopenharmony_ci#define kTopValue ((UInt32)1 << 24) 12370b324cSopenharmony_ci 13370b324cSopenharmony_ci 14370b324cSopenharmony_ci#define READ_BYTE(p) IByteIn_Read((p)->Stream) 15370b324cSopenharmony_ci 16370b324cSopenharmony_ciBoolInt Ppmd7z_RangeDec_Init(CPpmd7_RangeDec *p) 17370b324cSopenharmony_ci{ 18370b324cSopenharmony_ci unsigned i; 19370b324cSopenharmony_ci p->Code = 0; 20370b324cSopenharmony_ci p->Range = 0xFFFFFFFF; 21370b324cSopenharmony_ci if (READ_BYTE(p) != 0) 22370b324cSopenharmony_ci return False; 23370b324cSopenharmony_ci for (i = 0; i < 4; i++) 24370b324cSopenharmony_ci p->Code = (p->Code << 8) | READ_BYTE(p); 25370b324cSopenharmony_ci return (p->Code < 0xFFFFFFFF); 26370b324cSopenharmony_ci} 27370b324cSopenharmony_ci 28370b324cSopenharmony_ci#define RC_NORM_BASE(p) if ((p)->Range < kTopValue) \ 29370b324cSopenharmony_ci { (p)->Code = ((p)->Code << 8) | READ_BYTE(p); (p)->Range <<= 8; 30370b324cSopenharmony_ci 31370b324cSopenharmony_ci#define RC_NORM_1(p) RC_NORM_BASE(p) } 32370b324cSopenharmony_ci#define RC_NORM(p) RC_NORM_BASE(p) RC_NORM_BASE(p) }} 33370b324cSopenharmony_ci 34370b324cSopenharmony_ci// we must use only one type of Normalization from two: LOCAL or REMOTE 35370b324cSopenharmony_ci#define RC_NORM_LOCAL(p) // RC_NORM(p) 36370b324cSopenharmony_ci#define RC_NORM_REMOTE(p) RC_NORM(p) 37370b324cSopenharmony_ci 38370b324cSopenharmony_ci#define R (&p->rc.dec) 39370b324cSopenharmony_ci 40370b324cSopenharmony_ciZ7_FORCE_INLINE 41370b324cSopenharmony_ci// Z7_NO_INLINE 42370b324cSopenharmony_cistatic void Ppmd7z_RD_Decode(CPpmd7 *p, UInt32 start, UInt32 size) 43370b324cSopenharmony_ci{ 44370b324cSopenharmony_ci 45370b324cSopenharmony_ci 46370b324cSopenharmony_ci R->Code -= start * R->Range; 47370b324cSopenharmony_ci R->Range *= size; 48370b324cSopenharmony_ci RC_NORM_LOCAL(R) 49370b324cSopenharmony_ci} 50370b324cSopenharmony_ci 51370b324cSopenharmony_ci#define RC_Decode(start, size) Ppmd7z_RD_Decode(p, start, size); 52370b324cSopenharmony_ci#define RC_DecodeFinal(start, size) RC_Decode(start, size) RC_NORM_REMOTE(R) 53370b324cSopenharmony_ci#define RC_GetThreshold(total) (R->Code / (R->Range /= (total))) 54370b324cSopenharmony_ci 55370b324cSopenharmony_ci 56370b324cSopenharmony_ci#define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref)) 57370b324cSopenharmony_ci// typedef CPpmd7_Context * CTX_PTR; 58370b324cSopenharmony_ci#define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p) 59370b324cSopenharmony_civoid Ppmd7_UpdateModel(CPpmd7 *p); 60370b324cSopenharmony_ci 61370b324cSopenharmony_ci#define MASK(sym) ((unsigned char *)charMask)[sym] 62370b324cSopenharmony_ci// Z7_FORCE_INLINE 63370b324cSopenharmony_ci// static 64370b324cSopenharmony_ciint Ppmd7z_DecodeSymbol(CPpmd7 *p) 65370b324cSopenharmony_ci{ 66370b324cSopenharmony_ci size_t charMask[256 / sizeof(size_t)]; 67370b324cSopenharmony_ci 68370b324cSopenharmony_ci if (p->MinContext->NumStats != 1) 69370b324cSopenharmony_ci { 70370b324cSopenharmony_ci CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext); 71370b324cSopenharmony_ci unsigned i; 72370b324cSopenharmony_ci UInt32 count, hiCnt; 73370b324cSopenharmony_ci const UInt32 summFreq = p->MinContext->Union2.SummFreq; 74370b324cSopenharmony_ci 75370b324cSopenharmony_ci 76370b324cSopenharmony_ci 77370b324cSopenharmony_ci 78370b324cSopenharmony_ci count = RC_GetThreshold(summFreq); 79370b324cSopenharmony_ci hiCnt = count; 80370b324cSopenharmony_ci 81370b324cSopenharmony_ci if ((Int32)(count -= s->Freq) < 0) 82370b324cSopenharmony_ci { 83370b324cSopenharmony_ci Byte sym; 84370b324cSopenharmony_ci RC_DecodeFinal(0, s->Freq) 85370b324cSopenharmony_ci p->FoundState = s; 86370b324cSopenharmony_ci sym = s->Symbol; 87370b324cSopenharmony_ci Ppmd7_Update1_0(p); 88370b324cSopenharmony_ci return sym; 89370b324cSopenharmony_ci } 90370b324cSopenharmony_ci 91370b324cSopenharmony_ci p->PrevSuccess = 0; 92370b324cSopenharmony_ci i = (unsigned)p->MinContext->NumStats - 1; 93370b324cSopenharmony_ci 94370b324cSopenharmony_ci do 95370b324cSopenharmony_ci { 96370b324cSopenharmony_ci if ((Int32)(count -= (++s)->Freq) < 0) 97370b324cSopenharmony_ci { 98370b324cSopenharmony_ci Byte sym; 99370b324cSopenharmony_ci RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq) 100370b324cSopenharmony_ci p->FoundState = s; 101370b324cSopenharmony_ci sym = s->Symbol; 102370b324cSopenharmony_ci Ppmd7_Update1(p); 103370b324cSopenharmony_ci return sym; 104370b324cSopenharmony_ci } 105370b324cSopenharmony_ci } 106370b324cSopenharmony_ci while (--i); 107370b324cSopenharmony_ci 108370b324cSopenharmony_ci if (hiCnt >= summFreq) 109370b324cSopenharmony_ci return PPMD7_SYM_ERROR; 110370b324cSopenharmony_ci 111370b324cSopenharmony_ci hiCnt -= count; 112370b324cSopenharmony_ci RC_Decode(hiCnt, summFreq - hiCnt) 113370b324cSopenharmony_ci 114370b324cSopenharmony_ci p->HiBitsFlag = PPMD7_HiBitsFlag_3(p->FoundState->Symbol); 115370b324cSopenharmony_ci PPMD_SetAllBitsIn256Bytes(charMask) 116370b324cSopenharmony_ci // i = p->MinContext->NumStats - 1; 117370b324cSopenharmony_ci // do { MASK((--s)->Symbol) = 0; } while (--i); 118370b324cSopenharmony_ci { 119370b324cSopenharmony_ci CPpmd_State *s2 = Ppmd7_GetStats(p, p->MinContext); 120370b324cSopenharmony_ci MASK(s->Symbol) = 0; 121370b324cSopenharmony_ci do 122370b324cSopenharmony_ci { 123370b324cSopenharmony_ci unsigned sym0 = s2[0].Symbol; 124370b324cSopenharmony_ci unsigned sym1 = s2[1].Symbol; 125370b324cSopenharmony_ci s2 += 2; 126370b324cSopenharmony_ci MASK(sym0) = 0; 127370b324cSopenharmony_ci MASK(sym1) = 0; 128370b324cSopenharmony_ci } 129370b324cSopenharmony_ci while (s2 < s); 130370b324cSopenharmony_ci } 131370b324cSopenharmony_ci } 132370b324cSopenharmony_ci else 133370b324cSopenharmony_ci { 134370b324cSopenharmony_ci CPpmd_State *s = Ppmd7Context_OneState(p->MinContext); 135370b324cSopenharmony_ci UInt16 *prob = Ppmd7_GetBinSumm(p); 136370b324cSopenharmony_ci UInt32 pr = *prob; 137370b324cSopenharmony_ci UInt32 size0 = (R->Range >> 14) * pr; 138370b324cSopenharmony_ci pr = PPMD_UPDATE_PROB_1(pr); 139370b324cSopenharmony_ci 140370b324cSopenharmony_ci if (R->Code < size0) 141370b324cSopenharmony_ci { 142370b324cSopenharmony_ci Byte sym; 143370b324cSopenharmony_ci *prob = (UInt16)(pr + (1 << PPMD_INT_BITS)); 144370b324cSopenharmony_ci 145370b324cSopenharmony_ci // RangeDec_DecodeBit0(size0); 146370b324cSopenharmony_ci R->Range = size0; 147370b324cSopenharmony_ci RC_NORM_1(R) 148370b324cSopenharmony_ci /* we can use single byte normalization here because of 149370b324cSopenharmony_ci (min(BinSumm[][]) = 95) > (1 << (14 - 8)) */ 150370b324cSopenharmony_ci 151370b324cSopenharmony_ci // sym = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol; 152370b324cSopenharmony_ci // Ppmd7_UpdateBin(p); 153370b324cSopenharmony_ci { 154370b324cSopenharmony_ci unsigned freq = s->Freq; 155370b324cSopenharmony_ci CPpmd7_Context *c = CTX(SUCCESSOR(s)); 156370b324cSopenharmony_ci sym = s->Symbol; 157370b324cSopenharmony_ci p->FoundState = s; 158370b324cSopenharmony_ci p->PrevSuccess = 1; 159370b324cSopenharmony_ci p->RunLength++; 160370b324cSopenharmony_ci s->Freq = (Byte)(freq + (freq < 128)); 161370b324cSopenharmony_ci // NextContext(p); 162370b324cSopenharmony_ci if (p->OrderFall == 0 && (const Byte *)c > p->Text) 163370b324cSopenharmony_ci p->MaxContext = p->MinContext = c; 164370b324cSopenharmony_ci else 165370b324cSopenharmony_ci Ppmd7_UpdateModel(p); 166370b324cSopenharmony_ci } 167370b324cSopenharmony_ci return sym; 168370b324cSopenharmony_ci } 169370b324cSopenharmony_ci 170370b324cSopenharmony_ci *prob = (UInt16)pr; 171370b324cSopenharmony_ci p->InitEsc = p->ExpEscape[pr >> 10]; 172370b324cSopenharmony_ci 173370b324cSopenharmony_ci // RangeDec_DecodeBit1(size0); 174370b324cSopenharmony_ci 175370b324cSopenharmony_ci R->Code -= size0; 176370b324cSopenharmony_ci R->Range -= size0; 177370b324cSopenharmony_ci RC_NORM_LOCAL(R) 178370b324cSopenharmony_ci 179370b324cSopenharmony_ci PPMD_SetAllBitsIn256Bytes(charMask) 180370b324cSopenharmony_ci MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0; 181370b324cSopenharmony_ci p->PrevSuccess = 0; 182370b324cSopenharmony_ci } 183370b324cSopenharmony_ci 184370b324cSopenharmony_ci for (;;) 185370b324cSopenharmony_ci { 186370b324cSopenharmony_ci CPpmd_State *s, *s2; 187370b324cSopenharmony_ci UInt32 freqSum, count, hiCnt; 188370b324cSopenharmony_ci 189370b324cSopenharmony_ci CPpmd_See *see; 190370b324cSopenharmony_ci CPpmd7_Context *mc; 191370b324cSopenharmony_ci unsigned numMasked; 192370b324cSopenharmony_ci RC_NORM_REMOTE(R) 193370b324cSopenharmony_ci mc = p->MinContext; 194370b324cSopenharmony_ci numMasked = mc->NumStats; 195370b324cSopenharmony_ci 196370b324cSopenharmony_ci do 197370b324cSopenharmony_ci { 198370b324cSopenharmony_ci p->OrderFall++; 199370b324cSopenharmony_ci if (!mc->Suffix) 200370b324cSopenharmony_ci return PPMD7_SYM_END; 201370b324cSopenharmony_ci mc = Ppmd7_GetContext(p, mc->Suffix); 202370b324cSopenharmony_ci } 203370b324cSopenharmony_ci while (mc->NumStats == numMasked); 204370b324cSopenharmony_ci 205370b324cSopenharmony_ci s = Ppmd7_GetStats(p, mc); 206370b324cSopenharmony_ci 207370b324cSopenharmony_ci { 208370b324cSopenharmony_ci unsigned num = mc->NumStats; 209370b324cSopenharmony_ci unsigned num2 = num / 2; 210370b324cSopenharmony_ci 211370b324cSopenharmony_ci num &= 1; 212370b324cSopenharmony_ci hiCnt = (s->Freq & (unsigned)(MASK(s->Symbol))) & (0 - (UInt32)num); 213370b324cSopenharmony_ci s += num; 214370b324cSopenharmony_ci p->MinContext = mc; 215370b324cSopenharmony_ci 216370b324cSopenharmony_ci do 217370b324cSopenharmony_ci { 218370b324cSopenharmony_ci unsigned sym0 = s[0].Symbol; 219370b324cSopenharmony_ci unsigned sym1 = s[1].Symbol; 220370b324cSopenharmony_ci s += 2; 221370b324cSopenharmony_ci hiCnt += (s[-2].Freq & (unsigned)(MASK(sym0))); 222370b324cSopenharmony_ci hiCnt += (s[-1].Freq & (unsigned)(MASK(sym1))); 223370b324cSopenharmony_ci } 224370b324cSopenharmony_ci while (--num2); 225370b324cSopenharmony_ci } 226370b324cSopenharmony_ci 227370b324cSopenharmony_ci see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum); 228370b324cSopenharmony_ci freqSum += hiCnt; 229370b324cSopenharmony_ci 230370b324cSopenharmony_ci 231370b324cSopenharmony_ci 232370b324cSopenharmony_ci 233370b324cSopenharmony_ci count = RC_GetThreshold(freqSum); 234370b324cSopenharmony_ci 235370b324cSopenharmony_ci if (count < hiCnt) 236370b324cSopenharmony_ci { 237370b324cSopenharmony_ci Byte sym; 238370b324cSopenharmony_ci 239370b324cSopenharmony_ci s = Ppmd7_GetStats(p, p->MinContext); 240370b324cSopenharmony_ci hiCnt = count; 241370b324cSopenharmony_ci // count -= s->Freq & (unsigned)(MASK(s->Symbol)); 242370b324cSopenharmony_ci // if ((Int32)count >= 0) 243370b324cSopenharmony_ci { 244370b324cSopenharmony_ci for (;;) 245370b324cSopenharmony_ci { 246370b324cSopenharmony_ci count -= s->Freq & (unsigned)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break; 247370b324cSopenharmony_ci // count -= s->Freq & (unsigned)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break; 248370b324cSopenharmony_ci } 249370b324cSopenharmony_ci } 250370b324cSopenharmony_ci s--; 251370b324cSopenharmony_ci RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq) 252370b324cSopenharmony_ci 253370b324cSopenharmony_ci // new (see->Summ) value can overflow over 16-bits in some rare cases 254370b324cSopenharmony_ci Ppmd_See_UPDATE(see) 255370b324cSopenharmony_ci p->FoundState = s; 256370b324cSopenharmony_ci sym = s->Symbol; 257370b324cSopenharmony_ci Ppmd7_Update2(p); 258370b324cSopenharmony_ci return sym; 259370b324cSopenharmony_ci } 260370b324cSopenharmony_ci 261370b324cSopenharmony_ci if (count >= freqSum) 262370b324cSopenharmony_ci return PPMD7_SYM_ERROR; 263370b324cSopenharmony_ci 264370b324cSopenharmony_ci RC_Decode(hiCnt, freqSum - hiCnt) 265370b324cSopenharmony_ci 266370b324cSopenharmony_ci // We increase (see->Summ) for sum of Freqs of all non_Masked symbols. 267370b324cSopenharmony_ci // new (see->Summ) value can overflow over 16-bits in some rare cases 268370b324cSopenharmony_ci see->Summ = (UInt16)(see->Summ + freqSum); 269370b324cSopenharmony_ci 270370b324cSopenharmony_ci s = Ppmd7_GetStats(p, p->MinContext); 271370b324cSopenharmony_ci s2 = s + p->MinContext->NumStats; 272370b324cSopenharmony_ci do 273370b324cSopenharmony_ci { 274370b324cSopenharmony_ci MASK(s->Symbol) = 0; 275370b324cSopenharmony_ci s++; 276370b324cSopenharmony_ci } 277370b324cSopenharmony_ci while (s != s2); 278370b324cSopenharmony_ci } 279370b324cSopenharmony_ci} 280370b324cSopenharmony_ci 281370b324cSopenharmony_ci/* 282370b324cSopenharmony_ciByte *Ppmd7z_DecodeSymbols(CPpmd7 *p, Byte *buf, const Byte *lim) 283370b324cSopenharmony_ci{ 284370b324cSopenharmony_ci int sym = 0; 285370b324cSopenharmony_ci if (buf != lim) 286370b324cSopenharmony_ci do 287370b324cSopenharmony_ci { 288370b324cSopenharmony_ci sym = Ppmd7z_DecodeSymbol(p); 289370b324cSopenharmony_ci if (sym < 0) 290370b324cSopenharmony_ci break; 291370b324cSopenharmony_ci *buf = (Byte)sym; 292370b324cSopenharmony_ci } 293370b324cSopenharmony_ci while (++buf < lim); 294370b324cSopenharmony_ci p->LastSymbol = sym; 295370b324cSopenharmony_ci return buf; 296370b324cSopenharmony_ci} 297370b324cSopenharmony_ci*/ 298370b324cSopenharmony_ci 299370b324cSopenharmony_ci#undef kTopValue 300370b324cSopenharmony_ci#undef READ_BYTE 301370b324cSopenharmony_ci#undef RC_NORM_BASE 302370b324cSopenharmony_ci#undef RC_NORM_1 303370b324cSopenharmony_ci#undef RC_NORM 304370b324cSopenharmony_ci#undef RC_NORM_LOCAL 305370b324cSopenharmony_ci#undef RC_NORM_REMOTE 306370b324cSopenharmony_ci#undef R 307370b324cSopenharmony_ci#undef RC_Decode 308370b324cSopenharmony_ci#undef RC_DecodeFinal 309370b324cSopenharmony_ci#undef RC_GetThreshold 310370b324cSopenharmony_ci#undef CTX 311370b324cSopenharmony_ci#undef SUCCESSOR 312370b324cSopenharmony_ci#undef MASK 313