zlib 可以在不压缩文件其余部分的情况下删除填充吗?
Can zlib remove padding without compressing the rest of the file?
我正在寻找一种使用 zlib-1.2.5 应用特定压缩策略的方法。
我需要强制 zlib 打包文件而不实际压缩它。我想要压缩的唯一部分是文件末尾的 0 填充,因此输出文件没有它。输入文件大小从1MB到1GB不等,padding为512B。
这可以通过 zlib 实现吗?
编辑:
我正在编写的代码基于 Unreal Engine 4:
https://github.com/EpicGames/UnrealEngine/blob/release/Engine/Source/Runtime/Core/Private/Misc/Compression.cpp
static bool appCompressMemoryZLIB(void* CompressedBuffer, int32& CompressedSize, const void* UncompressedBuffer, int32 UncompressedSize, int32 BitWindow, int32 CompLevel)
{
DECLARE_SCOPE_CYCLE_COUNTER(TEXT("Compress Memory ZLIB"), STAT_appCompressMemoryZLIB, STATGROUP_Compression);
ensureMsgf(CompLevel >= Z_DEFAULT_COMPRESSION, TEXT("CompLevel must be >= Z_DEFAULT_COMPRESSION"));
ensureMsgf(CompLevel <= Z_BEST_COMPRESSION, TEXT("CompLevel must be <= Z_BEST_COMPRESSION"));
CompLevel = FMath::Clamp(CompLevel, Z_DEFAULT_COMPRESSION, Z_BEST_COMPRESSION);
// Zlib wants to use unsigned long.
unsigned long ZCompressedSize = CompressedSize;
unsigned long ZUncompressedSize = UncompressedSize;
bool bOperationSucceeded = false;
// Compress data
// If using the default Zlib bit window, use the zlib routines, otherwise go manual with deflate2
if (BitWindow == 0 || BitWindow == DEFAULT_ZLIB_BIT_WINDOW)
{
bOperationSucceeded = compress2((uint8*)CompressedBuffer, &ZCompressedSize, (const uint8*)UncompressedBuffer, ZUncompressedSize, CompLevel) == Z_OK ? true : false;
}
else
{
z_stream stream;
stream.next_in = (Bytef*)UncompressedBuffer;
stream.avail_in = (uInt)ZUncompressedSize;
stream.next_out = (Bytef*)CompressedBuffer;
stream.avail_out = (uInt)ZCompressedSize;
stream.zalloc = &zalloc;
stream.zfree = &zfree;
stream.opaque = Z_NULL;
if (ensure(Z_OK == deflateInit2(&stream, CompLevel, Z_DEFLATED, BitWindow, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY)))
{
if (ensure(Z_STREAM_END == deflate(&stream, Z_FINISH)))
{
ZCompressedSize = stream.total_out;
if (ensure(Z_OK == deflateEnd(&stream)))
{
bOperationSucceeded = true;
}
}
else
{
deflateEnd(&stream);
}
}
}
// Propagate compressed size from intermediate variable back into out variable.
CompressedSize = ZCompressedSize;
return bOperationSucceeded;
}
带参数:输入缓冲区大小 = 65kB,CompLevel=Z_DEFAULT_COMPRESSION,MAX_MEM_LEVEL=9,BitWindow=15
没有,没有。
如果您只想去掉末尾的零,那是微不足道的。就是几行代码。你不需要 zlib 的 18,000 行代码来做到这一点。
如果您还想将这些零恢复到另一端的文件(“解压缩它”),那也是微不足道的。只需发送已删除的零的计数,并将该计数附加到末尾的几个字节中。在另一端,用那么多零字节替换该计数。还有几行代码。
我正在寻找一种使用 zlib-1.2.5 应用特定压缩策略的方法。 我需要强制 zlib 打包文件而不实际压缩它。我想要压缩的唯一部分是文件末尾的 0 填充,因此输出文件没有它。输入文件大小从1MB到1GB不等,padding为512B。 这可以通过 zlib 实现吗?
编辑:
我正在编写的代码基于 Unreal Engine 4: https://github.com/EpicGames/UnrealEngine/blob/release/Engine/Source/Runtime/Core/Private/Misc/Compression.cpp
static bool appCompressMemoryZLIB(void* CompressedBuffer, int32& CompressedSize, const void* UncompressedBuffer, int32 UncompressedSize, int32 BitWindow, int32 CompLevel)
{
DECLARE_SCOPE_CYCLE_COUNTER(TEXT("Compress Memory ZLIB"), STAT_appCompressMemoryZLIB, STATGROUP_Compression);
ensureMsgf(CompLevel >= Z_DEFAULT_COMPRESSION, TEXT("CompLevel must be >= Z_DEFAULT_COMPRESSION"));
ensureMsgf(CompLevel <= Z_BEST_COMPRESSION, TEXT("CompLevel must be <= Z_BEST_COMPRESSION"));
CompLevel = FMath::Clamp(CompLevel, Z_DEFAULT_COMPRESSION, Z_BEST_COMPRESSION);
// Zlib wants to use unsigned long.
unsigned long ZCompressedSize = CompressedSize;
unsigned long ZUncompressedSize = UncompressedSize;
bool bOperationSucceeded = false;
// Compress data
// If using the default Zlib bit window, use the zlib routines, otherwise go manual with deflate2
if (BitWindow == 0 || BitWindow == DEFAULT_ZLIB_BIT_WINDOW)
{
bOperationSucceeded = compress2((uint8*)CompressedBuffer, &ZCompressedSize, (const uint8*)UncompressedBuffer, ZUncompressedSize, CompLevel) == Z_OK ? true : false;
}
else
{
z_stream stream;
stream.next_in = (Bytef*)UncompressedBuffer;
stream.avail_in = (uInt)ZUncompressedSize;
stream.next_out = (Bytef*)CompressedBuffer;
stream.avail_out = (uInt)ZCompressedSize;
stream.zalloc = &zalloc;
stream.zfree = &zfree;
stream.opaque = Z_NULL;
if (ensure(Z_OK == deflateInit2(&stream, CompLevel, Z_DEFLATED, BitWindow, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY)))
{
if (ensure(Z_STREAM_END == deflate(&stream, Z_FINISH)))
{
ZCompressedSize = stream.total_out;
if (ensure(Z_OK == deflateEnd(&stream)))
{
bOperationSucceeded = true;
}
}
else
{
deflateEnd(&stream);
}
}
}
// Propagate compressed size from intermediate variable back into out variable.
CompressedSize = ZCompressedSize;
return bOperationSucceeded;
}
带参数:输入缓冲区大小 = 65kB,CompLevel=Z_DEFAULT_COMPRESSION,MAX_MEM_LEVEL=9,BitWindow=15
没有,没有。
如果您只想去掉末尾的零,那是微不足道的。就是几行代码。你不需要 zlib 的 18,000 行代码来做到这一点。
如果您还想将这些零恢复到另一端的文件(“解压缩它”),那也是微不足道的。只需发送已删除的零的计数,并将该计数附加到末尾的几个字节中。在另一端,用那么多零字节替换该计数。还有几行代码。