> Hi everyone. I'm just finishing my own experimental encoder for Tiberian Sun VQAs and one of the areas I'd like to improve is the format80 encoder algorithm.
> I'm not versed in LZ77 or whatever compression scheme that is and my own encoder is crappy, very slow and produces files larger than necessary.
> I was wondering if anyone out there has written a good format80 encoder and is willing to share it with me, naturally you would be credited for the contribution!
Olaf has written it for XCC.
http://cvs.sourceforge.net/viewcvs.py/xccu/xcc/misc/shp_decode.cpp?rev=1.7&view=markup
int encode80(const byte* s, byte* d, int cb_s)
{
// full compression
const byte* s_end = s + cb_s;
const byte* r = s;
byte* w = d;
const byte* copy_from = NULL;
while (r < s_end)
{
byte* p;
int cb_p;
int t = get_run_length(r, s_end);
get_same(s, r, s_end, p, cb_p);
if (t < cb_p && cb_p > 2)
{
flush_c1(w, r, copy_from);
if (cb_p - 3 < 8 && r - p < 0x1000)
write80_c0(w, cb_p, r - p);
else if (cb_p - 3 < 0x3e)
write80_c2(w, cb_p, p - s);
else
write80_c4(w, cb_p, p - s);
r += cb_p;
}
else
{
if (t < 3)
{
if (!copy_from)
copy_from = r;
}
else
{
flush_c1(w, r, copy_from);
write80_c3(w, t, *r);
}
r += t;
}
}
flush_c1(w, r, copy_from);
write80_c1(w, 0, NULL);
return w - d;
}
int encode80_y(const byte* s, byte* d, int cb_s)
{
// run length encoding
const byte* r = s;
byte* w = d;
int count = 0;
byte last = ~*r;
while (cb_s--)
{
byte v = *r++;
if (last == v)
count++;
else
{
write_v80(last, count, w);
count = 1;
last = v;
}
}
write_v80(last, count, w);
*w++ = 0x80;
return w - d;
}
There are much more functions there which you will need to have this working (like write_v80, write80_c1, etc... Olaf's documentation might not be the best around, but after some effort, you'll be able to understand it
).