ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

7-Zip-zstd 中的 LZ5 压缩库:lz5、lz5hc 与 lz5frame 分层集成与使用指南

7-Zip-zstd 中的 LZ5 压缩库:lz5、lz5hc 与 lz5frame 分层集成与使用指南 桌面应用CLI【免费下载链接】7-Zip-zstd7-Zip with support for Brotli, Fast-LZMA2, Lizard, LZ4, LZ5 and Zstandard项目地址https://gitcode.com/gh_mirrors/7z/7-Zip-zstd点击查看免费下载LZ5 是 LZ4 家族中面向极高压缩/解压速度场景的块压缩算法本仓库7-Zip-zstd在 C/lz5/ 目录下完整集成了其全部库文件并在 7-Zip 中通过 Lz5Handler.cpp 提供了对 LZ5 帧格式magic0x184D2205的原生支持。本文以 C/lz5/README.md 为主线结合仓库内头文件与源码梳理如何按需挑选库文件、调用块级 API、启用高压缩模式lz5hc以及使用帧封装层lz5frame产出与命令行工具互通的数据流。读完本文你将掌握只用两个源文件接入最快路径的最小集成方式在压缩率换速度与速度换压缩率之间切换的 API 选择以及一套可落地的单块压缩/流式帧压缩 C 代码模板。LZ5 库文件构成按需取用不必全量引入README 开宗明义lib目录下的文件并非都需要。仓库实际快照中 C/lz5/ 目录包含以下源文件与头文件可以按三层依赖关系取用场景需要引入的文件说明最小编成快速压缩/解压lz5.c lz5.h提供完整的块级压缩与解压能力所有函数声明见 lz5.h更高压缩率上述基础上再加 lz5hc.c lz5hc.hlz5hc 只提供压缩函数解压函数仍复用 lz5其编译依赖 lz5与lz5命令行工具互通再加 lz5frame.c lz5frame.h将 LZ5 压缩块封装进官方可互操作帧格式内部依赖 lz5、lz5hc 以及用于错误检测的 xxhash静态链接专用lz5frame_static.hREADME 明确不建议使用定义不保证跨版本稳定仅用于静态链接关于帧层的依赖链README 特别指出lz5frame 需要 lz5 和 lz5hc同时需要xxhash提供错误检测算法高级用法中可以将 xxhash 符号隐藏进局部命名空间liblz5正是这样做的以避免用户程序同时链接多个含 xxhash 符号的库时发生符号重复。本仓库已在 C/hashes/ 目录内置了 xxhash.c 与 xxhash.h可以直接参与编译。README 还提到仓库应包含的非源码文件LICENSEBSD 许可文本、Makefile编译/安装脚本、liblz5.pc.in供make install后 pkg-config 使用。需要说明的是本仓库快照的 C/lz5/ 目录实际只保留了 LICENSE 与各源码文件Makefile与liblz5.pc.in未包含在内如需构建请参照 README 描述的依赖关系自行组织编译。关于 lz5frame_static.h 的谨慎使用lz5frame_static.h 是为静态链接准备的扩展头它把帧层内部错误码以LZ5F_errorCodes枚举的形式暴露出来OK_NoError、ERROR_decompressionFailed、ERROR_contentChecksum_invalid、ERROR_headerChecksum_invalid等共 20 个便于上层针对具体错误做精细处理。但正如文件头部注释所述这些定义仍可能随版本变化永远不要在 DLL 动态链接场景下使用它。块级压缩核心lz5.h API 全景lz5.h 声明了全部块级block-level接口。该头文件为编程者提供完整的缓冲区控制权如果需要自动管理内存、产出可互操作数据则应改用 lz5frame.h。当前版本号定义于头文件顶部LZ5_VERSION v1.5.0并可通过LZ5_versionNumber()在运行时获取LZ5_VERSION_NUMBER1.5.0 → 10500。调优参数与输入限制#define LZ5_MEMORY_USAGE 20 /* 内存用量公式N - 2^N 字节20 即 1 MB */ #define LZ5_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 字节约 1.97 GiB */ #define LZ5_COMPRESSBOUND(isize) ((unsigned)(isize) (unsigned)LZ5_MAX_INPUT_SIZE ? 0 : (isize) ((isize)/128) 16)LZ5_MEMORY_USAGE可调参数。内存用量按2^N字节计算10→1 KB12→4 KB16→64 KB20→1 MB。增大内存可提升压缩率减小内存可因缓存效应提速。该值同时决定哈希表规模——lz5.c 中LZ5_HASHLOG LZ5_MEMORY_USAGE - 2哈希表大小1 LZ5_HASHLOG。LZ5_MAX_INPUT_SIZE单次输入的最大支持值。LZ5_COMPRESSBOUND()最坏情况下数据不可压缩压缩输出的上界用于分配目标缓冲区也是编译期可求值的宏适合栈上定长数组。简单函数最快上手路径int LZ5_compress_default(const char* source, char* dest, int sourceSize, int maxDestSize); int LZ5_decompress_safe (const char* source, char* dest, int compressedSize, int maxDecompressedSize);LZ5_compress_default()将sourceSize字节压缩进容量为maxDestSize的dest缓冲区。若maxDestSize LZ5_compressBound(sourceSize)则压缩必然成功且运行更快推荐设置若预算不足压缩会立即停止并返回 0此时dest内容无效。函数保证不越界读写。LZ5_decompress_safe()compressedSize必须是压缩块的精确完整大小maxDecompressedSize是目标缓冲区容量。返回实际解出的字节数缓冲区不够或输入流被检测为畸形时返回负数。它是防缓冲区溢出攻击含恶意数据包的安全接口同样保证不越界读写。最小可运行示例#include lz5.h /* 压缩端为最坏情况预留空间 */ int srcSize (int)inputLen; int dstCap LZ5_compressBound(srcSize); char* compressed malloc(dstCap); int cSize LZ5_compress_default(input, compressed, srcSize, dstCap); if (cSize 0) { /* 压缩失败预算不足或输入超限 */ } /* 解压端目标缓冲区必须已分配 */ char* out malloc(dstCap); int r LZ5_decompress_safe(compressed, out, cSize, dstCap); if (r 0) { /* 流损坏或缓冲区过小 */ } else if (r ! srcSize) { /* 解出的字节数与预期不一致 */ }进阶函数加速、外部状态与定向输出LZ5_compress_fast()同默认函数但可选加速acceleration因子。加速值越大压缩越快、压缩率越低每递增 1 大致带来约 3% 速度提升。加速值 1 等价于默认函数 0的值会被替换为默认值 1见 lz5.c。LZ5_compress_fast_extState() / LZ5_sizeofState()使用外部分配的压缩状态内存需 8 字节对齐malloc通常满足。适合需要在多次压缩间复用状态、或希望精确控制内存的场景。LZ5_compress_destSize()反转逻辑——不是给定源压缩到足够大的目标而是给定目标容量targetDestSize尽可能多地压缩源数据塞满它*sourceSizePtr会被改写为实际从源中消费的字节数。LZ5_decompress_fast()传入原始未压缩大小originalSize返回实际读取的压缩字节数。它比LZ5_decompress_safe()略快但不提供对恶意篡改数据流的防护只应在可信环境中使用。LZ5_decompress_safe_partial()只要解出targetOutputSize字节就尽早停止用于降低解压耗时返回值可能小于目标值当压缩块本身更小时务必校验实际解码字节数。流式压缩与解压流式接口以上一块数据作为字典的方式持续提升压缩率字典窗口上限 64 KB。压缩侧lz5.hLZ5_stream_t跟踪流状态的结构体使用前必须初始化。静态链接可直接分配结构体并调用LZ5_resetStream()以 DLL 方式使用时应改用LZ5_createStream()/LZ5_freeStream()前者对未来结构体尺寸变化更稳健。LZ5_loadDict()将静态字典载入流载入前已有数据会被遗忘字典上限 64 KB载入 0 字节也允许。LZ5_compress_fast_continue()以前面压缩过的块为字典压缩新块。关键前提之前的数据块在压缩期间必须仍在原位且未被修改若maxDstSize LZ5_compressBound(srcSize)压缩必然成功且更快。LZ5_saveDict()若前一块数据无法保证留在原内存位置将其保存到更安全的缓冲区保存后无需再调LZ5_loadDict()可立即继续LZ5_compress_fast_continue()。解压侧lz5.hLZ5_streamDecode_t解压流状态使用前须用LZ5_setStreamDecode()或memset初始化同样推荐LZ5_createStreamDecode()/LZ5_freeStreamDecode()构造方式。LZ5_decompress_safe_continue()/LZ5_decompress_fast_continue()多块流式解压要求之前解出的数据最多 64 KB仍留在解码位置。环缓冲区场景有三种兼容方案编码/解码缓冲完全同步、解码缓冲比编码缓冲大至少一个 maxBlockSize、或解码缓冲至少 64 KB 8 字节 maxBlockSize条件不满足时用LZ5_saveDict思路保存末 64 KB 并经LZ5_setStreamDecode()指回。LZ5_decompress_safe_usingDict()/LZ5_decompress_fast_usingDict()等价于LZ5_setStreamDecode()后立即调用continue系列无需维护流结构独立使用。废弃接口提示lz5.h 保留了一批标记LZ5_DEPRECATED的旧接口如LZ5_compress、LZ5_compress_continue、LZ5_create、LZ5_slideInputBuffer等未来版本会触发警告并逐步移除README 与本仓库源码均建议迁移到上述维护中的新接口。若编译警告造成困扰可定义LZ5_DISABLE_DEPRECATE_WARNINGS关闭或对 gcc 使用-Wno-deprecated-declarations。高压缩模式lz5hc.h当默认速度模式下压缩率不足、又希望保持解压速度不变时用 lz5hc 换取压缩率的提升。lz5hc 的核心接口只有一处int LZ5_compress_HC (const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel);目标缓冲区dst必须已分配用LZ5_compressBound()见 lz5.h按最坏情况估算容量即可保证成功。compressionLevel推荐值4 ~ 90 到LZ5HC_MAX_CLEVEL15定义于 lz5.h之间的任意值均可用0 表示使用默认值见 lz5hc.c大于 15 的值按 15 处理。返回写入dst的字节数失败返回 0。解压无需 lz5hc——lz5hc.h 明确声明解压函数由 lz5 源码提供见 lz5.hBSD 许可因此 HC 模式解压端与普通模式共用同一套LZ5_decompress_*接口。配套能力外部状态LZ5_alloc_mem_HC()/LZ5_free_mem_HC()管理LZ5HC_Data_Structure或LZ5_sizeofStateHC()LZ5_compress_HC_extStateHC()手动分配8 字节对齐。流式LZ5_streamHC_tLZ5_STREAMHCSIZE为 262192 字节配合LZ5_createStreamHC(compressionLevel)、LZ5_resetStreamHC()、LZ5_loadDictHC()、LZ5_compress_HC_continue()、LZ5_saveDictHC()使用规则与普通流式压缩一致前一块最多 64 KB在压缩下一块时必须保持可读且未修改环形缓冲区小于 64 KB 的例外会被LZ5_compress_HC_continue()自动检测处理。帧封装层lz5frame.h 与可互操作数据流lz5frame.h 提供自包含的帧 API用于产出符合 LZ5 帧规范 v1.5.1 的数据从而与lz5命令行工具互通。使用 lz5frame 时不需要再包含 lz5.h——帧层自行完成内存管理与块调度。帧参数枚举与结构体typedef enum { LZ5F_default0, LZ5F_max64KB1, LZ5F_max256KB2, LZ5F_max1MB3, LZ5F_max4MB4, LZ5F_max16MB5, LZ5F_max64MB6, LZ5F_max256MB7 } LZ5F_blockSizeID_t;块大小档位LZ5F_blockSizeID_t取值与含义值名称含义0LZ5F_default使用默认块大小1 ~ 7LZ5F_max64KB~LZ5F_max256MB块内压缩数据的最大尺寸上限从 64 KB 到 256 MB 共七档其余枚举LZ5F_blockMode_tblockLinked0块间链接/blockIndependent块间独立、LZ5F_contentChecksum_tnoContentChecksum0/contentChecksumEnabled、LZ5F_frameType_tframe0/skippableFrame。typedef struct { LZ5F_blockSizeID_t blockSizeID; /* 0 default */ LZ5F_blockMode_t blockMode; /* 0 default */ LZ5F_contentChecksum_t contentChecksumFlag; /* 0 default */ LZ5F_frameType_t frameType; /* 0 default */ unsigned long long contentSize; /* 0 unknown */ unsigned reserved[2]; /* 必须为零保证前向兼容 */ } LZ5F_frameInfo_t; typedef struct { LZ5F_frameInfo_t frameInfo; int compressionLevel; /* 0 默认(快速模式)16 按 160 按 0 */ unsigned autoFlush; /* 1 总是 flush减少临时缓冲需求 */ unsigned reserved[4]; /* 必须为零 */ } LZ5F_preferences_t;错误管理所有返回size_t的帧接口都以错误码表达失败用LZ5F_isError(code)判断用LZ5F_getErrorName(code)取可读错误字符串便于调试。更细粒度的错误枚举仅存在于 lz5frame_static.h静态链接专用见上文。一步到位LZ5F_compressFramesize_t LZ5F_compressFrameBound(size_t srcSize, const LZ5F_preferences_t* preferencesPtr); size_t LZ5F_compressFrame(void* dstBuffer, size_t dstMaxSize, const void* srcBuffer, size_t srcSize, const LZ5F_preferences_t* preferencesPtr);整块 srcBuffer 压缩进一个完整 LZ5 帧。铁律dstBuffer必须足够大dstMaxSize即使最坏情况也要容纳完整输出——最小值用LZ5F_compressFrameBound()求得不满足则返回错误码。preferencesPtr可传NULL全部参数取默认值。成功返回写入 dst 的字节数。流式帧压缩五段式生命周期/* 1) 创建上下文version 必须是 LZ5F_VERSION100 */ LZ5F_compressionContext_t cctx; LZ5F_errorCode_t err LZ5F_createCompressionContext(cctx, LZ5F_VERSION); if (LZ5F_isError(err)) { /* 上下文创建失败 */ } /* 2) 写入帧头dstMaxSize 需容纳头部最大 15 字节 */ size_t written LZ5F_compressBegin(cctx, dst, dstCap, NULL /* 或 prefs */); /* 3) 循环喂数据可反复调用返回 0 表示数据只是被缓冲了 */ written LZ5F_compressUpdate(cctx, dst, dstCap, src, srcSize, NULL); /* (可选) 立即产出缓冲数据不等当前块填满 */ written LZ5F_flush(cctx, dst, dstCap, NULL); /* 4) 收尾flush 剩余数据并写结束标记与校验和4 字节开校验和则为 8 字节 */ written LZ5F_compressEnd(cctx, dst, dstCap, NULL); /* 5) 释放上下文成功后 cctx 可复用 */ LZ5F_freeCompressionContext(cctx);要点LZ5F_compressUpdate()每次的dstMaxSize仍须按LZ5F_compressBound(srcSize, prefs)预留该函数含帧结束代价4 字节开启帧校验和则为 8 字节它不保证错误可恢复出错后须重置上下文。LZ5F_compressOptions_t可选可传 NULL其中stableSrc1声明源内容在后续调用中保持不变可避免库把源数据复制进临时缓冲当作字典。流式帧解压循环驱动的 dctx 模型/* 1) 创建解压上下文 */ LZ5F_decompressionContext_t dctx; LZ5F_createDecompressionContext(dctx, LZ5F_VERSION); /* 2)可选解析帧头头部长度 7~15 字节可一次多喂入*srcSizePtr 会被改写为实际消费字节数 */ LZ5F_frameInfo_t fi; size_t srcConsumed srcSize; size_t hint LZ5F_getFrameInfo(dctx, fi, src, srcConsumed); /* 3) 循环解压直到函数返回 0帧已全部解码 */ size_t dstSize, srcSizeLeft /* 剩余压缩数据 */; do { dstSize dstCap; srcSize srcSizeLeft; hint LZ5F_decompress(dctx, dst, dstSize, src, srcSize, NULL); /* 消费 srcSize 字节产出 dstSize 字节dst 应在每次调用间被取走/覆盖 */ src srcSize; srcSizeLeft - srcSize; if (LZ5F_isError(hint)) { /* 解压失败 */ } } while (hint ! 0); /* 4) 释放若解压完整正确free 返回 0 */ LZ5F_freeDecompressionContext(dctx);LZ5F_decompress()的返回值是下次调用期望的 srcSize 字节数提示当前压缩块 下一块头部的大小遵守提示可跳过中间缓冲从而提速返回 0 表示帧解码完成此时 dctx 可复用于下一个帧。LZ5F_decompressOptions_t中的stableDst1可声明解码数据在后续调用中仍驻留避免被存入临时缓冲。在 7-Zip-zstd 中的实际集成源码级证据本仓库不仅内置了独立的 LZ5 库还把它接入了 7-Zip 的压缩/解压框架可作为如何在真实项目中落地的参照。帧识别Lz5Handler.cpp 中的IsArc_lz5()读取前 4 字节LZ5 帧魔数为0x184D2205同时兼容 skippable 帧魔数区间0x184D2A50~0x184D2A5F此时需再检查偏移 12 处的真正魔数。这验证了 lz5frame 与lz5命令行工具的帧格式在 7-Zip 侧的真实互通性。多线程封装7-Zip 的 LZ5 编码器并没有直接调用 lz5.c而是经由 C/zstdmt/lz5-mt.h 及 lz5-mt_compress.c 等文件的多线程包装。从 Lz5Encoder.cpp 可以看到线程数默认取处理器数量并夹紧到LZ5MT_THREAD_MAX-mx级别参数在LZ5MT_LEVEL_MIN与LZ5MT_LEVEL_MAX之间夹紧后再传给LZ5MT_createCCtx()。这提示了在集成 LZ5 时块级 API 适合单线程场景需要吞吐量扩展时应考虑多线程包装层。集成小结与推荐选型按 README 的三层结构选型决策可以简化为只需快速压缩/解压、数据自产自销仅引入 lz5.c lz5.h用LZ5_compress_default/LZ5_decompress_safe或加速与流式变体目标缓冲区一律按LZ5_compressBound()预留压缩率敏感、解压速度敏感追加 lz5hc.ccompressionLevel取 4~9解压端无需任何改动需要与lz5命令行工具或其它 LZ5 实现互通追加 lz5frame.c采用LZ5F_compressFrame或五段式流式压缩并注意其依赖 lz5、lz5hc 与 xxhash仓库内 C/hashes/xxhash.c 可直接编译。编译时按依赖关系组合源文件即可例如gcc -O3 -I C/lz5 -I C/hashes \ my_program.c C/lz5/lz5.c C/lz5/lz5hc.c C/lz5/lz5frame.c C/hashes/xxhash.c -o my_program最后再次强调 lz5frame_static.h 的边界它暴露的枚举与内部定义不受版本稳定性承诺保护仅限静态链接使用动态链接场景请只依赖 lz5frame.h 的公开接口与LZ5F_VERSION版本协商机制。赞分享桌面应用CLI【免费下载链接】7-Zip-zstd7-Zip with support for Brotli, Fast-LZMA2, Lizard, LZ4, LZ5 and Zstandard项目地址https://gitcode.com/gh_mirrors/7z/7-Zip-zstd点击查看免费下载相关推荐7-Zip-zstd 内置的 Lizard 压缩库C/lizard 源码结构、构建方式与 7-Zip 集成指南7 Zip zstd 内置的 Lizard 压缩库C/lizard 源码结构、构建方式与 7 Zip 集成指南 Lizard 是一个快速的 LZ 压缩算法库桌面应用CLI7-Zip-zstd终极指南支持Zstd/Brotli的超级压缩工具7 Zip zstd终极指南支持Zstd/Brotli的超级压缩工具 7 Zip zstd是一款革命性的开源压缩工具它在经典7 Zip基础上集成了Zstan桌面应用CLILazyCraft工作流引擎详解可视化编程如何提升AI开发效率LazyCraft工作流引擎详解可视化编程如何提升AI开发效率 LazyCraft是一款功能强大的AI开发工具其核心工作流引擎通过可视化编程方式让开发者无桌面应用CLI上一篇Elephant高级技巧自定义主题与个性化设置全指南下一篇bilibili-helper-o弹幕系统揭秘从解码到发送人查询创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表