/****************************************************************************** * * * Copyright (C) 1992-1995 Tony Robinson * * * * See the file doc/LICENSE.shorten for conditions on distribution and usage * * * ******************************************************************************/ /* * $Id: vario.c,v 1.10 2004/05/04 02:26:36 jason Exp $ */ #include #include #include #include "shorten.h" #define MASKTABSIZE 33 ulong masktab[MASKTABSIZE]; void mkmasktab() { int i; ulong val = 0; masktab[0] = val; for(i = 1; i < MASKTABSIZE; i++) { val <<= 1; val |= 1; masktab[i] = val; } } void var_get_init(shn_file *this_shn) { mkmasktab(); this_shn->decode_state->getbuf = (uchar*) pmalloc((ulong) BUFSIZ,this_shn); this_shn->decode_state->getbufp = this_shn->decode_state->getbuf; this_shn->decode_state->nbyteget = 0; this_shn->decode_state->gbuffer = 0; this_shn->decode_state->nbitget = 0; } ulong word_get(shn_file *this_shn) { ulong buffer; int bytes; if(this_shn->decode_state->nbyteget < 4) { this_shn->vars.last_file_position = this_shn->vars.bytes_read; bytes = deadbeef->fread((uchar*) this_shn->decode_state->getbuf, 1, BUFSIZ, this_shn->vars.fd); this_shn->decode_state->nbyteget += bytes; if(this_shn->decode_state->nbyteget < 4) { shn_error_fatal(this_shn,"Premature EOF on compressed stream -\npossible corrupt or truncated file"); return (ulong)0; } this_shn->vars.bytes_read += bytes; this_shn->decode_state->getbufp = this_shn->decode_state->getbuf; } buffer = (((slong) (this_shn->decode_state->getbufp[0])) << 24) | (((slong) (this_shn->decode_state->getbufp[1])) << 16) | (((slong) (this_shn->decode_state->getbufp[2])) << 8) | ((slong) (this_shn->decode_state->getbufp[3])); this_shn->decode_state->getbufp += 4; this_shn->decode_state->nbyteget -= 4; return(buffer); } slong uvar_get(int nbin,shn_file *this_shn) { slong result; if (this_shn->vars.reading_function_code) { this_shn->vars.last_file_position_no_really = this_shn->vars.last_file_position; } if(this_shn->decode_state->nbitget == 0) { this_shn->decode_state->gbuffer = word_get(this_shn); if (this_shn->vars.fatal_error) return (ulong)0; this_shn->decode_state->nbitget = 32; } for(result = 0; !(this_shn->decode_state->gbuffer & (1L << --(this_shn->decode_state->nbitget))); result++) { if(this_shn->decode_state->nbitget == 0) { this_shn->decode_state->gbuffer = word_get(this_shn); if (this_shn->vars.fatal_error) return (ulong)0; this_shn->decode_state->nbitget = 32; } } while(nbin != 0) { if(this_shn->decode_state->nbitget >= nbin) { result = (result << nbin) | ((this_shn->decode_state->gbuffer >> (this_shn->decode_state->nbitget-nbin)) &masktab[nbin]); this_shn->decode_state->nbitget -= nbin; nbin = 0; } else { result = (result << this_shn->decode_state->nbitget) | (this_shn->decode_state->gbuffer & masktab[this_shn->decode_state->nbitget]); this_shn->decode_state->gbuffer = word_get(this_shn); if (this_shn->vars.fatal_error) return (ulong)0; nbin -= this_shn->decode_state->nbitget; this_shn->decode_state->nbitget = 32; } } return(result); } ulong ulong_get(shn_file *this_shn) { unsigned int nbit = uvar_get(ULONGSIZE,this_shn); if (this_shn->vars.fatal_error) return (ulong)0; return(uvar_get(nbit,this_shn)); } slong var_get(int nbin,shn_file *this_shn) { ulong uvar = uvar_get(nbin + 1,this_shn); if (this_shn->vars.fatal_error) return (slong)0; if(uvar & 1) return((slong) ~(uvar >> 1)); else return((slong) (uvar >> 1)); } void var_get_quit(shn_file *this_shn) { free((void *) this_shn->decode_state->getbuf); this_shn->decode_state->getbuf = NULL; }