aboutsummaryrefslogtreecommitdiff
path: root/arith.c
diff options
context:
space:
mode:
Diffstat (limited to 'arith.c')
-rw-r--r--arith.c244
1 files changed, 244 insertions, 0 deletions
diff --git a/arith.c b/arith.c
new file mode 100644
index 0000000..784946f
--- /dev/null
+++ b/arith.c
@@ -0,0 +1,244 @@
+/*
+ * Compface - 48x48x1 image compression and decompression
+ *
+ * Copyright (c) James Ashton - Sydney University - June 1990.
+ *
+ * Written 11th November 1989.
+ *
+ * Permission is given to distribute these sources, as long as the
+ * copyright messages are not removed, and no monies are exchanged.
+ *
+ * No responsibility is taken for any errors on inaccuracies inherent
+ * either to the comments or the code of this program, but if reported
+ * to me, then an attempt will be made to fix them.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "compface.h"
+
+void
+RevPush(p)
+Prob *p;
+{
+ if (NumProbs >= PIXELS * 2 - 1)
+ longjmp(comp_env, ERR_INTERNAL);
+ ProbBuf[NumProbs++] = p;
+}
+
+void
+BigPush(p)
+Prob *p;
+{
+ static WORD tmp;
+
+ BigDiv(p->p_range, &tmp);
+ BigMul(0);
+ BigAdd(tmp + p->p_offset);
+}
+
+int
+BigPop(p)
+register Prob *p;
+{
+ static WORD tmp;
+ register int i;
+
+ BigDiv(0, &tmp);
+ i = 0;
+ while ((tmp < p->p_offset) || (tmp >= p->p_range + p->p_offset))
+ {
+ p++;
+ i++;
+ }
+ BigMul(p->p_range);
+ BigAdd(tmp - p->p_offset);
+ return i;
+}
+
+#ifdef DEBUG
+/* Print a BigInt in HexaDecimal
+ */
+void
+BigPrint()
+{
+ register int i, c, count;
+ register WORD *w;
+
+ count = 0;
+ w = B.b_word + (i = B.b_words);
+ while (i--)
+ {
+ w--;
+ c = *((*w >> 4) + HexDigits);
+ putc(c, stderr);
+ c = *((*w & 0xf) + HexDigits);
+ putc(c, stderr);
+ if (++count >= 36)
+ {
+ putc('\\', stderr);
+ putc('\n', stderr);
+ count = 0;
+ }
+ }
+ putc('\n', stderr);
+}
+#endif
+
+/* Divide B by a storing the result in B and the remainder in the word
+ * pointer to by r
+ */
+void
+BigDiv(a, r)
+register WORD a, *r;
+{
+ register int i;
+ register WORD *w;
+ register COMP c, d;
+
+ a &= WORDMASK;
+ if ((a == 1) || (B.b_words == 0))
+ {
+ *r = 0;
+ return;
+ }
+ if (a == 0) /* treat this as a == WORDCARRY */
+ { /* and just shift everything right a WORD */
+ i = --B.b_words;
+ w = B.b_word;
+ *r = *w;
+ while (i--)
+ {
+ *w = *(w + 1);
+ w++;
+ }
+ *w = 0;
+ return;
+ }
+ w = B.b_word + (i = B.b_words);
+ c = 0;
+ while (i--)
+ {
+ c <<= BITSPERWORD;
+ c += (COMP)*--w;
+ d = c / (COMP)a;
+ c = c % (COMP)a;
+ *w = (WORD)(d & WORDMASK);
+ }
+ *r = c;
+ if (B.b_word[B.b_words - 1] == 0)
+ B.b_words--;
+}
+
+/* Multiply a by B storing the result in B
+ */
+void
+BigMul(a)
+register WORD a;
+{
+ register int i;
+ register WORD *w;
+ register COMP c;
+
+ a &= WORDMASK;
+ if ((a == 1) || (B.b_words == 0))
+ return;
+ if (a == 0) /* treat this as a == WORDCARRY */
+ { /* and just shift everything left a WORD */
+ if ((i = B.b_words++) >= MAXWORDS - 1)
+ longjmp(comp_env, ERR_INTERNAL);
+ w = B.b_word + i;
+ while (i--)
+ {
+ *w = *(w - 1);
+ w--;
+ }
+ *w = 0;
+ return;
+ }
+ i = B.b_words;
+ w = B.b_word;
+ c = 0;
+ while (i--)
+ {
+ c += (COMP)*w * (COMP)a;
+ *(w++) = (WORD)(c & WORDMASK);
+ c >>= BITSPERWORD;
+ }
+ if (c)
+ {
+ if (B.b_words++ >= MAXWORDS)
+ longjmp(comp_env, ERR_INTERNAL);
+ *w = (COMP)(c & WORDMASK);
+ }
+}
+
+#if 0
+/* Subtract a from B storing the result in B
+ */
+void
+BigSub(a)
+WORD a;
+{
+ register int i;
+ register WORD *w;
+ register COMP c;
+
+ a &= WORDMASK;
+ if (a == 0)
+ return;
+ i = 1;
+ w = B.b_word;
+ c = (COMP)*w - (COMP)a;
+ *w = (WORD)(c & WORDMASK);
+ while (c & WORDCARRY)
+ {
+ if (i >= B.b_words)
+ longjmp(comp_env, ERR_INTERNAL);
+ c = (COMP)*++w - 1;
+ *w = (WORD)(c & WORDMASK);
+ i++;
+ }
+ if ((i == B.b_words) && (*w == 0) && (i > 0))
+ B.b_words--;
+}
+#endif
+
+/* Add to a to B storing the result in B
+ */
+void
+BigAdd(a)
+WORD a;
+{
+ register int i;
+ register WORD *w;
+ register COMP c;
+
+ a &= WORDMASK;
+ if (a == 0)
+ return;
+ i = 0;
+ w = B.b_word;
+ c = a;
+ while ((i < B.b_words) && c)
+ {
+ c += (COMP)*w;
+ *w++ = (WORD)(c & WORDMASK);
+ c >>= BITSPERWORD;
+ i++;
+ }
+ if ((i == B.b_words) && c)
+ {
+ if (B.b_words++ >= MAXWORDS)
+ longjmp(comp_env, ERR_INTERNAL);
+ *w = (COMP)(c & WORDMASK);
+ }
+}
+
+void
+BigClear()
+{
+ B.b_words = 0;
+}