1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 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);
}
|