static DWORD rng_decompress(BYTE *out, BYTE *in, DWORD in_len) { qsmodel qsm; rangecoder rc; int ch, syfreq, ltfreq; DWORD act_uncomprlen = 0; /* make an alphabet with 257 symbols, use 256 as end-of-file */ initqsmodel(&qsm, 257, 12, 2000, NULL, 0); /* unknown crypt_index[0], seems to be always 0x00 */ start_decoding(&rc, in + 1); while (1) { ltfreq = decode_culshift(&rc, 12); ch = qsgetsym(&qsm, ltfreq); if (ch == 256) /* check for end-of-file */ break; out[act_uncomprlen++] = ch; qsgetfreq(&qsm, ch, &syfreq, <freq); decode_update(&rc, syfreq, ltfreq, 1 << 12); qsupdate(&qsm, ch); } qsgetfreq(&qsm, 256, &syfreq, <freq); decode_update(&rc, syfreq, ltfreq, 1 << 12); done_decoding(&rc); deleteqsmodel(&qsm); return act_uncomprlen; }
/* rescale frequency counts */ static void dorescale( qsmodel *m) { int i, cf, missing; if (m->nextleft) /* we have some more before actual rescaling */ { m->incr++; m->left = m->nextleft; m->nextleft = 0; return; } if (m->rescale < m->targetrescale) /* double rescale interval if needed */ { m->rescale <<= 1; if (m->rescale > m->targetrescale) m->rescale = m->targetrescale; } cf = missing = m->cf[m->n]; /* do actual rescaling */ for(i=m->n-1; i; i--) { int tmp = m->newf[i]; cf -= tmp; m->cf[i] = cf; tmp = tmp>>1 | 1; missing -= tmp; m->newf[i] = tmp; } if (cf!=m->newf[0]) { fprintf(stderr,"BUG: rescaling left %d total frequency\n",cf); deleteqsmodel(m); exit(1); } m->newf[0] = m->newf[0]>>1 | 1; missing -= m->newf[0]; m->incr = missing / m->rescale; m->nextleft = missing % m->rescale; m->left = m->rescale - m->nextleft; if (m->search != NULL) { i=m->n; while (i) { int start, end; end = (m->cf[i]-1) >> m->searchshift; i--; start = m->cf[i] >> m->searchshift; while (start<=end) { m->search[start] = i; start++; } } }