70 lines
1.5 KiB
C++
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
|