Think I may be doing something wrong here, but... give it a try
#include <cstring>
#include <fstream>
#include <iostream>
#include <numeric>
#include <string>
#include <vector>
int main(int argc, char **argv)
{
std::ifstream inf;
std::ofstream outf;
char *buf = new char[4096];
char c;
unsigned inlen = 0, outlen = 0;
std::vector<bool> data;
auto p = data.begin();
inf.open(argv[1], std::ifstream::binary);
inf.seekg(0, inf.end);
inlen = inf.tellg();
inf.seekg(0, inf.beg);
inf.read(buf, 4);
if (std::strncmp(buf, "sszl", 4) != 0) return 1;
std::memset(buf, 0, 4);
inf.read((char*)&outlen, 4);
std::cout << inlen << " / " << outlen << '\n';
inf.seekg(4, inf.cur);
while (inf.get(c))
for (int i = 0; i < 8; i++)
data.push_back((bool)((c >> i) & 1));
inf.close();
unsigned j = 0;
unsigned o = 0;
outf.open(std::string(argv[1])+".uncompressed", std::ofstream::binary);
for (int i = 0; i < data.size();)
{
if ((bool)data[i++])
{
char k = std::accumulate(data.begin()+i, data.begin()+(i+8), 0,
[](char x, char y)
{
return (x<<1)+y;
});
std::memmove(buf+(j%4096), &k, 1);
outf.put(k);
i+=8;
j++;
}
else
{
o = std::accumulate(data.begin()+i, data.begin()+(i+12), 0,
[](unsigned x, unsigned y)
{
return (x<<1)+y;
})-1;
unsigned k = std::accumulate(data.begin()+i, data.begin()+(i+4), 0,
[](unsigned x, unsigned y)
{
return (x<<1)+y;
})+2;
o %= 4096;
for (int m = 0; m < k; m++)
{
buf[(j+m)%4096]=buf[o];
outf.put(buf[o]);
o=(o+1)%4096;
i+=16;
j+=o;
}
}
}
outf.close();
/*for (auto i: data) std::cout << (i ? 1 : 0);
std::cout << '\n';*/
return 0;
}