示例#1
0
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, &ltfreq);
        decode_update(&rc, syfreq, ltfreq, 1 << 12);
        qsupdate(&qsm, ch);
	}
    qsgetfreq(&qsm, 256, &syfreq, &ltfreq);
    decode_update(&rc, syfreq, ltfreq, 1 << 12);
    done_decoding(&rc);
    deleteqsmodel(&qsm);

	return act_uncomprlen;
}
示例#2
0
/* 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++;
            }
        }
    }