lightningbolt/lib/bolt/Compression.cpp

70 lines
1.5 KiB
C++

#include <bolt/Compression.hpp>
#include "bolt/Errors.hpp"
namespace lightningbolt {
ErrorOr<std::vector<u8>> BoltDecompress(u8* input, usize decompressedSize) {
u8* inptr = input;
std::vector<u8> res;
res.resize(decompressedSize);
u8* pOut = res.data();
u8* pEnd = res.data() + decompressedSize;
i32 iVar3 = 0;
i32 iVar6 = 0;
u32 uVar5 = 0;
u8* pbVar4 = nullptr; // outrun
bool bVar1;
while(pOut < pEnd) {
auto uVar7 = *inptr++;
if(uVar7 < 128) { // lookback/run?
iVar3 = iVar3 + uVar5 * 8 + ((int)(uVar7 & 0x70) >> 4);
pbVar4 = pOut + -(iVar6 * 0x10 + (uVar7 & 0xf) + 1);
iVar6 = iVar3 + 1;
if(iVar3 != -2) {
do {
*pOut = *pbVar4;
pbVar4 = pbVar4 + 1;
bVar1 = iVar6 != 0;
pOut = pOut + 1;
iVar6 = iVar6 + -1;
} while(bVar1);
}
iVar6 = 0;
iVar3 = 0;
uVar5 = 0;
} else if(uVar7 < 144) { // literal copy from stream
iVar3 = uVar5 * 0x10 + (uVar7 & 0xf) + 1;
while(iVar3 != 0) {
iVar3 = iVar3 + -1;
*pOut = *inptr++;
pOut = pOut + 1;
}
iVar3 = 0;
uVar5 = 0;
} else if(uVar7 < 160) {
uVar5 = uVar7 & 3;
iVar3 = iVar3 + 1;
iVar6 = (int)(uVar7 & 0xc) >> 2;
} else if(uVar7 < 192) {
uVar5 = uVar5 * 0x20 + (uVar7 & 0x1f);
iVar3 = iVar3 + 1;
} else {
iVar3 = iVar3 + 1;
iVar6 = iVar6 * 0x40 + (uVar7 & 0x3f);
}
}
if(pOut != pEnd)
return std::make_error_code(BoltErrc::DecompressionError);
return res;
}
} // namespace lightningbolt