implement RLE decode

This commit is contained in:
2019-02-08 14:44:34 +01:00
parent d8f23adb35
commit 1876207afb
2 changed files with 60 additions and 3 deletions

View File

@@ -134,14 +134,39 @@ std::shared_ptr<ABR::Image> ABR::parse_vmem()
auto rect = rrect(); auto rect = rrect();
auto depth2 = ru16(); // again? auto depth2 = ru16(); // again?
auto compression = ru8(); // 1 = zip auto compression = ru8(); // 1 = zip
if (compression != 0 || depth != 8) if (depth != 8)
{
printf("unsupported depth %d bits\n", depth);
skip(length - 23);
continue;
}
if (compression == 0)
{
int data_size = (depth >> 3) * rect.area();
ret->channels.emplace_back(depth, rect, compression, rraw(data_size));
}
else if (compression == 1)
{
auto height = rect.height();
// contain the compressed length of each scanline
std::vector<uint16_t> scanlines;
scanlines.reserve(height);
for (int i = 0; i < height; i++)
scanlines.push_back(ru16());
std::vector<uint8_t> raw;
for (auto sl : scanlines)
{
auto decoded = rrle(sl);
raw.insert(raw.end(), decoded.begin(), decoded.end());
}
ret->channels.emplace_back(depth, rect, compression, raw);
}
else
{ {
printf("unsupported compression mode %d\n", compression); printf("unsupported compression mode %d\n", compression);
skip(length - 23); skip(length - 23);
continue; continue;
} }
int data_size = (depth >> 3) * rect.area();
ret->channels.emplace_back(depth, rect, compression, rraw(data_size));
} }
snap(); snap();
return ret; return ret;

View File

@@ -85,6 +85,38 @@ public:
skip(bytes); skip(bytes);
return ret; return ret;
} }
std::vector<uint8_t> rrle(size_t encoded_bytes)
{
std::vector<uint8_t> data;
int32_t n;
for (int j = 0; j < encoded_bytes;)
{
n = ri8();
j++;
// force sign
if (n >= 128)
n -= 256; // can this even happen?
// copy the following char -n + 1 times
if (n < 0)
{
// NOP
if (n == -128)
continue;
n = -n + 1;
j++;
for (int c = 0; c < n; c++)
data.push_back(ru8());
}
else
{
// read the following n + 1 chars (no compr)
for (int c = 0; c < n + 1; c++, j++)
data.push_back(ru8());
}
}
return data;
}
protected: protected:
template<typename T> inline T align4(T x) { return ((x - T{1}) & (~(T{3}))) + T{4}; } template<typename T> inline T align4(T x) { return ((x - T{1}) & (~(T{3}))) + T{4}; }
template<typename T> T read() template<typename T> T read()