aboutsummaryrefslogtreecommitdiff
path: root/compress.c
diff options
context:
space:
mode:
Diffstat (limited to 'compress.c')
-rw-r--r--compress.c205
1 files changed, 205 insertions, 0 deletions
diff --git a/compress.c b/compress.c
new file mode 100644
index 0000000..3c97806
--- /dev/null
+++ b/compress.c
@@ -0,0 +1,205 @@
+/*
+ * 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"
+
+int
+Same(f, wid, hei)
+register char *f;
+register int wid, hei;
+{
+ register char val, *row;
+ register int x;
+
+ val = *f;
+ while (hei--)
+ {
+ row = f;
+ x = wid;
+ while (x--)
+ if (*(row++) != val)
+ return(0);
+ f += WIDTH;
+ }
+ return 1;
+}
+
+int
+AllBlack(f, wid, hei)
+char *f;
+int wid, hei;
+{
+ if (wid > 3)
+ {
+ wid /= 2;
+ hei /= 2;
+ return (AllBlack(f, wid, hei) && AllBlack(f + wid, wid, hei) &&
+ AllBlack(f + WIDTH * hei, wid, hei) &&
+ AllBlack(f + WIDTH * hei + wid, wid, hei));
+ }
+ else
+ return (*f || *(f + 1) || *(f + WIDTH) || *(f + WIDTH + 1));
+}
+
+int
+AllWhite(f, wid, hei)
+char *f;
+int wid, hei;
+{
+ return ((*f == 0) && Same(f, wid, hei));
+}
+
+void
+PopGreys(f, wid, hei)
+char *f;
+int wid, hei;
+{
+ if (wid > 3)
+ {
+ wid /= 2;
+ hei /= 2;
+ PopGreys(f, wid, hei);
+ PopGreys(f + wid, wid, hei);
+ PopGreys(f + WIDTH * hei, wid, hei);
+ PopGreys(f + WIDTH * hei + wid, wid, hei);
+ }
+ else
+ {
+ wid = BigPop(freqs);
+ if (wid & 1)
+ *f = 1;
+ if (wid & 2)
+ *(f + 1) = 1;
+ if (wid & 4)
+ *(f + WIDTH) = 1;
+ if (wid & 8)
+ *(f + WIDTH + 1) = 1;
+ }
+}
+
+void
+PushGreys(f, wid, hei)
+char *f;
+int wid, hei;
+{
+ if (wid > 3)
+ {
+ wid /= 2;
+ hei /= 2;
+ PushGreys(f, wid, hei);
+ PushGreys(f + wid, wid, hei);
+ PushGreys(f + WIDTH * hei, wid, hei);
+ PushGreys(f + WIDTH * hei + wid, wid, hei);
+ }
+ else
+ RevPush(freqs + *f + 2 * *(f + 1) + 4 * *(f + WIDTH) +
+ 8 * *(f + WIDTH + 1));
+}
+
+void
+UnCompress(f, wid, hei, lev)
+register char *f;
+register int wid, hei, lev;
+{
+ switch (BigPop(&levels[lev][0]))
+ {
+ case WHITE :
+ return;
+ case BLACK :
+ PopGreys(f, wid, hei);
+ return;
+ default :
+ wid /= 2;
+ hei /= 2;
+ lev++;
+ UnCompress(f, wid, hei, lev);
+ UnCompress(f + wid, wid, hei, lev);
+ UnCompress(f + hei * WIDTH, wid, hei, lev);
+ UnCompress(f + wid + hei * WIDTH, wid, hei, lev);
+ return;
+ }
+}
+
+void
+Compress(f, wid, hei, lev)
+register char *f;
+register int wid, hei, lev;
+{
+ if (AllWhite(f, wid, hei))
+ {
+ RevPush(&levels[lev][WHITE]);
+ return;
+ }
+ if (AllBlack(f, wid, hei))
+ {
+ RevPush(&levels[lev][BLACK]);
+ PushGreys(f, wid, hei);
+ return;
+ }
+ RevPush(&levels[lev][GREY]);
+ wid /= 2;
+ hei /= 2;
+ lev++;
+ Compress(f, wid, hei, lev);
+ Compress(f + wid, wid, hei, lev);
+ Compress(f + hei * WIDTH, wid, hei, lev);
+ Compress(f + wid + hei * WIDTH, wid, hei, lev);
+}
+
+void
+UnCompAll(fbuf)
+char *fbuf;
+{
+ register char *p;
+
+ BigClear();
+ BigRead(fbuf);
+ p = F;
+ while (p < F + PIXELS)
+ *(p++) = 0;
+ UnCompress(F, 16, 16, 0);
+ UnCompress(F + 16, 16, 16, 0);
+ UnCompress(F + 32, 16, 16, 0);
+ UnCompress(F + WIDTH * 16, 16, 16, 0);
+ UnCompress(F + WIDTH * 16 + 16, 16, 16, 0);
+ UnCompress(F + WIDTH * 16 + 32, 16, 16, 0);
+ UnCompress(F + WIDTH * 32, 16, 16, 0);
+ UnCompress(F + WIDTH * 32 + 16, 16, 16, 0);
+ UnCompress(F + WIDTH * 32 + 32, 16, 16, 0);
+}
+
+void
+CompAll(fbuf)
+char *fbuf;
+{
+ Compress(F, 16, 16, 0);
+ Compress(F + 16, 16, 16, 0);
+ Compress(F + 32, 16, 16, 0);
+ Compress(F + WIDTH * 16, 16, 16, 0);
+ Compress(F + WIDTH * 16 + 16, 16, 16, 0);
+ Compress(F + WIDTH * 16 + 32, 16, 16, 0);
+ Compress(F + WIDTH * 32, 16, 16, 0);
+ Compress(F + WIDTH * 32 + 16, 16, 16, 0);
+ Compress(F + WIDTH * 32 + 32, 16, 16, 0);
+ BigClear();
+ while (NumProbs > 0)
+ BigPush(ProbBuf[--NumProbs]);
+ BigWrite(fbuf);
+}