diff src/shnplug/vario.c @ 1305:51bf0e431e02

Add SHNplug.
author William Pitcock <nenolod@atheme-project.org>
date Fri, 20 Jul 2007 10:29:54 -0500
parents
children fa9f85cebade
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/shnplug/vario.c	Fri Jul 20 10:29:54 2007 -0500
@@ -0,0 +1,146 @@
+/******************************************************************************
+*                                                                             *
+*  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 <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#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 = vfs_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;
+}