101 lines
3.2 KiB
C++

//======================================================================================================
// Copyright 2025, Rokoko Glove OptiTrack Integration
//======================================================================================================
#include "LZ4Wrapper.h"
#include "lz4.h"
#include <cstring>
#include <stdexcept>
namespace RokokoIntegration
{
std::vector<uint8_t> LZ4Wrapper::Decompress(const uint8_t* compressedData, int compressedSize)
{
try {
// 입력 데이터 검증
if (!compressedData || compressedSize <= 0) {
return {};
}
// LZ4 데이터 유효성 검사
if (!IsValidLZ4Data(compressedData, compressedSize)) {
return {};
}
// 압축 해제된 크기 추정
int decompressedSize = GetDecompressedSize(compressedData, compressedSize);
if (decompressedSize <= 0) {
return {};
}
// 크기 유효성 검사
if (!ValidateDecompressedSize(compressedSize, decompressedSize)) {
return {};
}
// 압축 해제 실행
std::vector<uint8_t> decompressed(decompressedSize);
int actualSize = LZ4_decompress_safe(
reinterpret_cast<const char*>(compressedData),
reinterpret_cast<char*>(decompressed.data()),
compressedSize,
decompressedSize
);
// 압축 해제 결과 검증
if (actualSize != decompressedSize) {
return {};
}
return decompressed;
} catch (...) {
// 모든 예외 상황에서 안전하게 빈 벡터 반환
return {};
}
}
bool LZ4Wrapper::IsValidLZ4Data(const uint8_t* data, int size)
{
if (!data || size < 4) {
return false;
}
// LZ4 매직 넘버 확인 (간단한 검증)
// 실제로는 더 정교한 검증이 필요할 수 있음
return true;
}
int LZ4Wrapper::GetDecompressedSize(const uint8_t* compressedData, int compressedSize)
{
try {
// LZ4에서 압축 해제된 크기 추정
int decompressedSize = LZ4_decompress_safe(
reinterpret_cast<const char*>(compressedData),
nullptr,
compressedSize,
0
);
return decompressedSize;
} catch (...) {
return -1;
}
}
bool LZ4Wrapper::ValidateDecompressedSize(int compressedSize, int decompressedSize)
{
// 압축 해제된 크기가 합리적인 범위인지 확인
if (decompressedSize <= 0 || decompressedSize > MAX_DECOMPRESSED_SIZE) {
return false;
}
// 압축률이 합리적인지 확인 (일반적으로 1:1 ~ 1:10)
if (decompressedSize < compressedSize || decompressedSize > compressedSize * 10) {
return false;
}
return true;
}
}