forked from alterware/iw6-mod
Added helper util functions for (de)compression.
This commit is contained in:
parent
50aa4097bb
commit
51e831cbfe
@ -109,6 +109,86 @@ namespace utils::compression
|
||||
result.resize(length);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::uint8_t> decompress(std::span<const std::uint8_t> input, std::size_t exp_output_size, double growth_rate)
|
||||
{
|
||||
auto decompress_internal = [](std::uint8_t* output, uLong* output_size, const std::uint8_t* input, uLong* input_size)
|
||||
{
|
||||
return uncompress2(
|
||||
reinterpret_cast<Bytef*>(output), output_size,
|
||||
reinterpret_cast<const Bytef*>(input), input_size
|
||||
);
|
||||
};
|
||||
|
||||
auto output_size = static_cast<uLong>(std::max(exp_output_size, std::size_t(256)));
|
||||
std::vector<std::uint8_t> output(output_size);
|
||||
|
||||
auto input_size = static_cast<uLong>(input.size());
|
||||
auto status = decompress_internal(output.data(), &output_size, input.data(), &input_size);
|
||||
|
||||
if (status == Z_BUF_ERROR)
|
||||
{
|
||||
const auto decompression_ratio = (input_size / static_cast<double>(output.size())) - 0.04;
|
||||
output_size = static_cast<uLong>(std::max(input.size() / decompression_ratio, static_cast<double>(output_size)));
|
||||
output.resize(output_size);
|
||||
|
||||
input_size = static_cast<uLong>(input.size());
|
||||
status = decompress_internal(output.data(), &output_size, input.data(), &input_size);
|
||||
}
|
||||
|
||||
for (growth_rate = std::max(growth_rate, 1.0); status == Z_BUF_ERROR;)
|
||||
{
|
||||
output_size = 4 + static_cast<uLong>(growth_rate * output.size());
|
||||
output.resize(output_size);
|
||||
|
||||
input_size = static_cast<uLong>(input.size());
|
||||
status = decompress_internal(output.data(), &output_size, input.data(), &input_size);
|
||||
}
|
||||
|
||||
if (status != Z_OK)
|
||||
{
|
||||
output.clear();
|
||||
return output;
|
||||
}
|
||||
|
||||
output.resize(output_size);
|
||||
return output;
|
||||
}
|
||||
|
||||
std::vector<std::uint8_t> compress(std::span<const std::uint8_t> input, std::size_t exp_output_size, double growth_rate)
|
||||
{
|
||||
auto compress_internal = [](std::uint8_t* output, uLong* output_size, const std::uint8_t* input, uLong input_size)
|
||||
{
|
||||
return compress2(
|
||||
reinterpret_cast<Bytef*>(output), output_size,
|
||||
reinterpret_cast<const Bytef*>(input), input_size,
|
||||
Z_BEST_COMPRESSION
|
||||
);
|
||||
};
|
||||
|
||||
auto output_size = static_cast<uLong>(std::max(exp_output_size, std::size_t(256)));
|
||||
std::vector<std::uint8_t> output(output_size);
|
||||
|
||||
const auto input_size = static_cast<uLong>(input.size());
|
||||
auto status = compress_internal(output.data(), &output_size, input.data(), input_size);
|
||||
|
||||
for (growth_rate = std::max(growth_rate, 1.0); status == Z_BUF_ERROR;)
|
||||
{
|
||||
output_size = 4 + static_cast<uLong>(growth_rate * output.size());
|
||||
output.resize(output_size);
|
||||
|
||||
status = compress_internal(output.data(), &output_size, input.data(), input_size);
|
||||
}
|
||||
|
||||
if (status != Z_OK)
|
||||
{
|
||||
output.clear();
|
||||
return output;
|
||||
}
|
||||
|
||||
output.resize(output_size);
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
namespace zip
|
||||
|
@ -1,7 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#define CHUNK 16384u
|
||||
|
||||
@ -11,6 +13,9 @@ namespace utils::compression
|
||||
{
|
||||
std::string compress(const std::string& data);
|
||||
std::string decompress(const std::string& data);
|
||||
|
||||
std::vector<std::uint8_t> compress(std::span<const std::uint8_t> input, std::size_t exp_output_size, double growth_rate = 2.0);
|
||||
std::vector<std::uint8_t> decompress(std::span<const std::uint8_t> input, std::size_t exp_output_size, double growth_rate = 2.0);
|
||||
}
|
||||
|
||||
namespace zip
|
||||
|
Loading…
x
Reference in New Issue
Block a user