Ejemplo n.º 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;
}
Ejemplo n.º 2
0
int unpack(FILE* out,FILE* in) 
{
	freq cf;
	rangecoder rc;
	struct buffer buffer;
	struct ari_model model;
	size_t processed=0;

	buffer.offset = 0;
	buffer.len_power = 1+BLOCKSIZE_POWER;
	buffer.len = 1<<buffer.len_power;
	buffer.len_mask = buffer.len - 1;
	buffer.data = malloc(buffer.len);
	rc.in = in;
	model_setup(&model);

	if(!buffer.data)
		return -2;

	if (start_decoding(&rc) != 0) {   
		return -1;
	}

	while ( (cf = decode_culfreq(&rc,2)) ) {   
		freq i, blocksize;

		decode_update(&rc,1,1,2);

		blocksize = decode_short(&rc) | ((size_t)decode_short(&rc)) <<16;

		for (i=0; i<blocksize; i++) {   
			freq symbol;

			cf = decode_culfreq(&rc,model.counts[SYMBOLS]);

			symbol =  model_get_symbol(&model, cf);
			decode_update(&rc, model.counts[symbol+1]-model.counts[symbol],model.counts[symbol],model.counts[SYMBOLS]);
			model_update_freq(&model,symbol);

			/*fprintf(stderr,"Decoding:%d(%c),%ld,%ld\n",symbol,symbol,counts[symbol+1]-counts[symbol],counts[symbol]);*/

			if(symbol > 0xff) {
				const uint8_t extra_bits = code_to_length[symbol-0x100].extra_bits;
				const size_t  extra_data = decode_culshift(&rc, extra_bits);

				const size_t  length = code_to_length[symbol-0x100].start + extra_data;
				size_t distance;
				size_t distance_hi;

				decode_update_shift(&rc, 1, extra_data, extra_bits);

				distance = decode_culshift(&rc,8);
				decode_update_shift(&rc, 1, distance, 8);

				distance_hi = decode_culshift(&rc,8);
				decode_update_shift(&rc, 1, distance_hi, 8);

				distance |= distance_hi<<8;

				/* fprintf(stderr,"Retrieved length,distance:%ld,%ld\n",length,distance);*/
				buffer.offset = copy_back_bytes(&buffer,buffer.offset,distance,length);
			}
			else {
				buffer.data[buffer.offset++] = symbol;
				if(buffer.offset >= buffer.len) {
					buffer.offset = 0;
					fwrite(buffer.data,1,buffer.len,out);
				}
			}
		}
		processed += blocksize;
		if(processed > 1<<19) {
			done_decoding(&rc);
			start_decoding(&rc);
			processed=0;
		}
		/*fprintf(stderr,"%ld;;%d\n",blocksize,model.counts[SYMBOLS]);*/
       	}
	fwrite(buffer.data,1,buffer.offset,out);
	done_decoding(&rc);
	model_done(&model);
	free(buffer.data);

	fclose(out);
	return 0;
}