恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
Lizard 熵编码子库全解析:FSE 与 Huffman 编解码器的文件选型、实现原理与 Lizard 集成路径
首页
资讯中心
/
Lizard 熵编码子库全解析:FSE 与 Huffman 编解码器的文件选型、实现原理与 Lizard 集成路径
Lizard 熵编码子库全解析:FSE 与 Huffman 编解码器的文件选型、实现原理与 Lizard 集成路径
发布时间:2026/9/28 8:21:02
桌面应用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点击查看免费下载本篇技术指南以 Lizard 熵编码子库的官方说明文档 ENTROPY.md 为骨架结合 7-Zip-zstd 仓库中 C/lizard 目录下的实际源码系统讲解 Lizard 所集成的新一代熵编码库New Generation Entropy library简称 NGE的文件构成、FSE有限状态熵与 Huffman 两种编解码器的工作流程以及它们如何在 Lizard 压缩管线levels 30–49中被实际调用。读完本文你将能够准确判断哪些熵编码文件是必需的、理解 FSE 的 tANS 状态机原理与 HUF 的 4X 分块编码机制并掌握通过LIZARD_NO_HUFFMAN等编译开关裁剪 Lizard 功能的实战方法。一、背景Lizard 中的熵编码子库是什么Lizard 是一个以 LZ 类字典压缩为基础的压缩算法库其核心由 lizard_compress.c、lizard_decompress.c 以及 lizard_common.h 中的等级表驱动。在 LZ 阶段匹配查找、距离编码、字面量流分离之后Lizard 还引入了一套独立的熵编码阶段对分离出的字面量流literals stream等中间数据使用 Huffman 编码进一步压缩。这套熵编码实现源自 Yann Collet 维护的 FiniteStateEntropy 项目被 Lizard 以子库形式集成在C/lizard目录中。根据 ENTROPY.md 的说明这个lib目录仓库中即 C/lizard包含多个文件但并非所有文件在每种使用场景下都需要。文档给出了一份详细清单帮助开发者按需取舍——这正是本文要完整展开的骨架内容。需要特别说明的是与上游原版文件命名不同本仓库将这些熵编码源文件统一加了liz_前缀如fse_compress.c→ liz_fse_compress.c并在部分公共基础设施上直接复用同仓库 zstd 子库的实现以去重。下文会逐一指出对应关系。二、文件清单与选型指南2.1 必须文件所有场景都需要ENTROPY.md 明确列出 5 个任何情况下都必须的文件文件仓库内实际路径职责error_public.h错误码列表以枚举enum形式公开error_private.h错误管理实现返回码编码、错误名查询mem.h底层内存访问例程大小端读取、字节序工具bitstream.h对所有熵编解码器通用的位流读写接口liz_entropy_common.c压缩与解压缩共用的公共函数对应原文档的entropy_common.c仓库中的两个细节值得注意符号去重原文档中的mem.h、bitstream.h在仓库中并非独立实现而是薄封装——bitstream.h 只有几行直接#include ../zstd/bitstream.h并复用ZSTD_highbit32hist.h 同样重定向到../zstd/hist.h即 zstd/hist.h提供FSE_count符号统计。这是为了避免同一仓库内 zstd 与 Lizard 两份熵编码代码产生符号重复。符号命名冲突解决fse.h 和 huf.h 头部定义了一组宏把LIZ_FSE_*/LIZ_HUF_*符号映射到独立的NGEF_*/NGEH_*命名空间如#define LIZ_FSE_isError NGEF_isError、#define LIZ_HUF_compressBound NGEH_compressBound从而避免与 zstd 内部的同名 FSE/HUF 符号冲突。2.2 有限状态熵FSE基础编解码器FSE 是其他编解码器依赖的基础编解码器。ENTROPY.md 的原文描述是它实现了一种 tANStable-based Asymmetric Numeral System变体压缩率接近算术编码但速度远快于算术编码压缩与解压缩可独立编译。文件职责fse.h暴露全部公共接口liz_fse_compress.cFSE 压缩编解码器实现对应原文档fse_compress.cliz_fse_decompress.cFSE 解压缩编解码器实现对应原文档fse_decompress.cFSE 的压缩/解压流程在 fse.h 中有权威定义本文后续第 3 节将展开。2.3 FSE 16-bit 符号版本fseU16ENTROPY.md 提到一个可选模块fseU16能够编码大于 256 的字母表每个符号占 2 字节编译依赖基础 FSE 编解码器压缩与解压缩合并在同一文件中fseU16.c实现、fseU16.h暴露接口。需要如实说明在当前 7-Zip-zstd 仓库的 C/lizard 目录中并未收录fseU16.c/fseU16.h。从仓库文件列表看仅存在基础 FSE、Huffman 与公共基础设施。因此本仓库的 Lizard 构建使用不到该模块如果需要 16-bit 符号支持需自行从上游 FiniteStateEntropy 项目补齐且要遵循本文第 6 节的命名/符号适配方式。2.4 Huffman 编解码器HUFENTROPY.md 将 HUF 定位为快速的 Huffman 编解码器需要基础 FSE 编解码器来压缩它的表头headers压缩与解压缩可独立编译。文件职责huf.h暴露全部公共接口liz_huf_compress.cHuffman 压缩实现对应原文档huf_compress.cliz_huf_decompress.cHuffman 解压缩实现对应原文档huf_decompress.cHUF 是 Lizard 等级 30–49 真正在压缩路径中使用的熵编码器第 5 节会给出其在 lizard_compress.c 中的真实调用证据。三、FSE有限状态熵的源码级原理3.1 为什么需要有限状态FSE 采用 tANS基于查表的非对称数字系统思路不再为每个符号单独编码固定长度码字而是维护一个状态state通过状态转移把信息分摊到近似符号熵的比特数上。这一设计的直接收益是压缩率逼近算术编码接近理论熵界而实现开销只是几次查表与移位速度远快于算术编码——这也正是 ENTROPY.md 所说similar to arithmetic in compression performance, but much faster的技术含义。3.2 压缩五步与解压三步流程fse.h 定义了标准流程FSE_compress() 步骤 1. 用 FSE_count() 统计源数据各符号出现次数实现见 zstd/hist.h 提供的 hist 模块 2. 用 LIZ_FSE_normalizeCount() 归一化计数使 sum(count[]) 2^tableLog 3. 用 LIZ_FSE_writeNCount() 把归一化计数紧凑地写入头部缓冲区 4. 用 FSE_buildCTable() 依据归一化计数构建编码表 CTable 5. 用 LIZ_FSE_compress_usingCTable() 用 CTable 编码数据流 FSE_decompress() 步骤 1. 用 LIZ_FSE_readNCount() 读回归一化计数 2. 用 FSE_buildDTable() 构建解码表 DTable 3. 用 FSE_decompress_usingDTable() 解码数据流这套分层 API 的意义在于CTable/DTable 可以跨多个数据块复用。例如上层可以先压缩多个块共享同一统计表或完全由外部方法保存/提供归一化分布这正是 Lizard 这类上层压缩器需要的灵活性。3.3 符号级 API编码与解码是逆向的LIFOfse.h 进一步暴露了符号级symbol-level的细粒度接口用于自定义流编码侧FSE_initCState()初始化状态 →FSE_encodeSymbol()逐符号编码单次最多输出tableLog位→FSE_flushCState()冲刷最终状态 →BIT_closeCStream()关闭位流返回字节数。解码侧FSE_initDState()读取初始状态 →FSE_decodeSymbol()逐符号解码 →FSE_endOfDState()校验状态归零。关键性质文档明确强调编码和解码以相反方向进行——你最先编码的符号是最后才解码的如同 LIFO 栈后进先出。因此调用方必须按逆序处理多状态流同时约定任意位字段最多允许nbBits 25以保证 32 位解码器的兼容性。解码端还提供了FSE_reloadDStream()的四种返回状态用于流边界检测BIT_DStream_unfinished还有数据、BIT_DStream_endOfBuffer到达缓冲区末尾、BIT_DStream_completed精确到达终点、BIT_DStream_tooFar越界数据损坏。3.4 关键调优参数与容量宏从 fse.h 可提取以下编译期常量理解它们对选择表大小、内存占用至关重要宏默认值含义FSE_MAX_MEMORY_USAGE14内存上限 2^14 16 KB表大小提升可改善压缩率FSE_DEFAULT_MEMORY_USAGE13默认 2^13 8 KB兼顾缓存友好性FSE_MAX_SYMBOL_VALUE255允许的最大符号值决定栈分配大小FSE_MIN_TABLELOG5tableLog 最小值FSE_TABLELOG_ABSOLUTE_MAX15tableLog 绝对上限其中FSE_MAX_TABLELOG FSE_MAX_MEMORY_USAGE - 2默认 12。文档注释特别指出推荐FSE_MAX_MEMORY_USAGE为 1416 KB因为该尺寸恰好能装入 Intel x86 的 L1 缓存。容量估算宏包括FSE_NCOUNTBOUND 512、FSE_BLOCKBOUND(size) (size (size7) 4 sizeof(size_t))、FSE_COMPRESSBOUND(size) FSE_NCOUNTBOUND FSE_BLOCKBOUND(size)静态分配表尺寸FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) 1 (1(maxTableLog-1)) ((maxSymbolValue1)*2)FSE_DTABLE_SIZE_U32(maxTableLog) 1 (1maxTableLog)。压缩侧还有零成本小优化工具FSE_buildCTable_raw()均匀分布、LIZ_FSE_buildCTable_rle()恒同符号等价 RLE以及带外部 scratch 缓冲区的FSE_compress_wksp()/LIZ_FSE_buildCTable_wksp()系列便于将工作区完全静态化。四、Huffman 编解码器HUF的源码级原理4.1 压缩五步与解压三步流程huf.h 定义了 HUF 的完整流程HUF_compress() 步骤 1. 用 FSE_count()暴露在 fse.h 中统计符号出现次数 2. 可选用 LIZ_HUF_optimalTableLog() 优化 tableLog 3. 用 HUF_buildCTable() 从计数构建 Huffman 编码表 CTable 4. 用 HUF_writeCTable() 将编码表紧凑写入内存 5. 用 LIZ_HUF_compress4X_usingCTable() 编码数据流 HUF_decompress() 步骤 1. 用 LIZ_HUF_selectDecoder() 依据启发式指标选择解码器X1 单符号 / X2 双符号 2. 用 HUF_readDTableX1/X2_wksp() 从保存的表构建解码表 3. 用 HUF_decompress?X?_usingDTable() 并行解码 1 段或 4 段注意4X命名HUF 会把输入块切成 4 段并行编码/解码对应HUF_compress4X_*/HUF_decompress4X_*另有单流变体HUF_compress1X_*/HUF_decompress1X_*。这种 4 段并行设计利用现代 CPU 的多发射与指令级并行是 HUF 速度优势的来源之一。LIZ_HUF_selectDecoder()返回 0X1或 1X2假设0 dstSize 128 KB。4.2 关键常量宏默认值含义HUF_TABLELOG_MAX12运行时 tableLog 上限受静态分配约束HUF_TABLELOG_DEFAULT11未指定时的默认 tableLogHUF_TABLELOG_ABSOLUTEMAX15绝对上限超过则代码不可用HUF_SYMBOLVALUE_MAX255最大符号值HUF_BLOCKSIZE_MAX128 KB单块最大输入尺寸HUF_WORKSPACE_SIZE(610)256压缩工作区最小尺寸HUF_DECOMPRESS_WORKSPACE_SIZE210解压工作区最小尺寸tableLog12 时约 1.5 KB工具函数方面HUF_estimateCompressedSize()与HUF_validateCTable()可在真正编码前估算压缩后大小并校验旧表是否仍适用配合HUF_repeat_none / HUF_repeat_check / HUF_repeat_valid三态与HUF_compress4X_repeat()实现跨块复用上一次编码表的优化——这与 FSE 的 CTable 复用思想一致且能显著减少头部开销。4.3 一个独特差异HUF 能处理不可压缩与 RLE 数据与 FSE 不同HUF_decompress()要求调用方传入精确的原始尺寸originalSize因此它可以正确重建cSrcSize1RLE与cSrcSizedstSize未压缩两种情况而 fse.h 明确警告FSE_decompress()不处理不可压缩与 RLE 数据——因为 FSE 缺乏头部信息这个判别责任被刻意委托给上层用户由上层根据块类型选择memcpy()未压缩或memset()单字节重复作为替代路径。五、熵编码在 Lizard 压缩管线中的真实集成熵编码并非孤立的模块——在 Lizard 的压缩流程中Huffman 被用来压缩字面量流。证据在 lizard_compress.c 的Lizard_writeStream()函数中FORCE_INLINE int Lizard_writeStream(int useHuff, Lizard_stream_t* ctx, BYTE* streamPtr, uint32_t streamLen, BYTE** op, BYTE* oend) { if (useHuff streamLen 1024) { #ifndef LIZARD_NO_HUFFMAN ... ctx-comprStreamLen (U32)HUF_compress(ctx-huffBase, ctx-huffEnd - ctx-huffBase, streamPtr, streamLen); ... if (ctx-comprStreamLen 0 (LIZARD_MINIMAL_HUFF_GAIN(ctx-comprStreamLen) streamLen)) { /* compressible */ /* 写入 24-bit 原始长度 24-bit 压缩长度 压缩数据 */ } #else return -1; /* 编译时禁用了 Huffman */ #endif } ... }从中可以提取三个集成细节启用阈值只有streamLen 1024字节的字面量流才尝试 Huffman 压缩小流直接原样存储节省头部开销。增益检查调用HUF_compress()后若LIZARD_MINIMAL_HUFF_GAIN(comprStreamLen) streamLen才采纳压缩结果否则回退为明文写入——即压缩后必须真正变小才值得。头部格式采纳时每段写入3 字节原始长度 3 字节压缩长度 压缩数据MEM_writeLE24让解码端能精确还原。等级侧的证据在 lizard_common.h等级表Lizard_levels中level 30–49 的条目整体被#ifndef LIZARD_NO_HUFFMAN包裹。也就是说启用熵编码时 Lizard 支持完整 10–49 级禁用后仅保留 10–29 级。这与 lizard/README.md 的编译说明完全一致见下节。六、裁剪与构建LIZARD_NO_HUFFMAN及文件取舍6.1 编译开关README.md 给出了基于熵编码文件取舍的三种构建形态仅 Lizard_raw、level 10–29编译时加-DLIZARD_NO_HUFFMAN无需熵编码目录下的任何文件Lizard_raw、level 10–49保留entropy目录即本仓库 C/lizard 下的熵编码文件全部文件Lizard_frame带帧格式、level 10–49额外需要lizard_frame*文件以及 xxhash 目录帧格式依赖 xxhash 做内容校验。宏的作用位置在 lizard_common.h未定义LIZARD_NO_HUFFMAN时LIZARD_COMPRESS_ADD_HUF取LIZ_HUF_compressBound(LIZARD_BLOCK_SIZE_PAD)LIZARD_HUF_BLOCK_SIZE等于整块大小定义后两者分别退化为 0 和 1即完全不预留 Huffman 缓冲区。6.2 按需取文件的完整决策表综合 ENTROPY.md 的清单与本仓库实际路径可以给出如下决策表使用场景必须包含的文件可选/不需要任何 FSE/HUF 用法error_public.h、error_private.h、mem.h、bitstream.h、liz_entropy_common.c及依赖的 zstd/hist.h、zstd/bitstream.h—仅 FSE 基础编解码上面 5 项 fse.h、liz_fse_compress.c、liz_fse_decompress.chuf.h、liz_huf_*.cFSE 16-bit 符号fseU16基础 FSE 全部文件本仓库未收录该模块需自行从上游补齐Huffman 编解码基础 FSE 全部文件HUF 头部依赖 FSE 压缩 huf.h、liz_huf_compress.c、liz_huf_decompress.c—Lizard 完整构建level 10–49上述全部熵编码文件 lizard_common.h、lizard_compress.c 等主库文件仅当需帧格式时再加 lizard_frame.c、lizard_frame.h 等值得一提的依赖关系来自 ENTROPY.md 的明确说明Huffman 依赖基础 FSE 来压缩它的表头——HUF 的头部huffWeight权重数组正是由FSE_decompress_wksp(..., 6)解码的证据见 liz_entropy_common.c其中注释指出 6 是 HUF 头部最大可能的 tableLog。因此只想要 Huffman、不想要 FSE在架构上不成立。七、错误处理统一的错误码体系所有熵编码 API 的返回值统一通过LIZ_FSE_isError()/LIZ_HUF_isError()判断用LIZ_FSE_getErrorName()/LIZ_HUF_getErrorName()获取可读错误名两者底层共享同一实现见 liz_entropy_common.c。错误码本体定义在 error_public.htypedef enum { FSE_error_no_error, FSE_error_GENERIC, FSE_error_dstSize_tooSmall, FSE_error_srcSize_wrong, FSE_error_corruption_detected, FSE_error_tableLog_tooLarge, FSE_error_maxSymbolValue_tooLarge, FSE_error_maxSymbolValue_tooSmall, FSE_error_workSpace_tooSmall, FSE_error_maxCode } FSE_ErrorCode;在 fse.h 的 API 注释中各函数的返回值契约高度一致可归纳为三条通则返回0数据不可压缩FSE_compress*系或无法装入目标缓冲*_usingCTable系——调用方应回退为明文/RLE 存储返回1仅 FSE 压缩系源数据是单符号重复应改用 RLEisError()为真返回的是错误码用getErrorName()定位具体原因。八、总结与阅读建议围绕 ENTROPY.md本文完成了以下闭环文件选型必选 5 项 FSE 3 项 HUF 3 项→原理剖析FSE 的 tANS 状态机与压缩/解压流程、HUF 的 4X 并行与表头复用→集成验证Lizard_writeStream()中streamLen 1024的启用阈值与增益检查、level 30–49 的编译期开关→构建裁剪-DLIZARD_NO_HUFFMAN与三种构建形态。如果你要继续深入推荐按以下路径阅读仓库源码想理解符号级位流操作阅读 bitstream.h 指向的 zstd/bitstream.h 与 fse.h 的内联实现想理解 HUF 建表与 4X 编码细节liz_huf_compress.c含huffNodeTable节点表与HUF_compress4X_repeat()想理解归一化计数在头部中的紧凑序列化liz_fse_compress.c 中的LIZ_FSE_writeNCount_generic()想理解错误管理error_private.h 与 liz_entropy_common.c。这套FSE 做熵编码底座、Huffman 做快速块编码的组合正是 Lizard 在高压缩等级30–49下兼顾压缩率与速度的关键也是理解该算法在 7-Zip-zstd 项目中定位的重要入口。赞分享桌面应用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点击查看免费下载相关推荐Loki 依赖解析klauspost/compress/fse 有限状态熵FSE编码原理与源码实现Loki 依赖解析klauspost/compress/fse 有限状态熵FSE编码原理与源码实现 本文围绕 Loki 仓库中 vendored 的 FS文档教程游戏开发深入解析 linuxkit 内置的 Finite State EntropyFSE熵编码库原理、API 与源码实现深入解析 linuxkit 内置的 Finite State EntropyFSE熵编码库原理、API 与源码实现 本文围绕 linuxkit 仓库中随源操作系统云原生容器运行时OpenCloud 中 vendored 的 Finite State EntropyFSE熵编码原理、Go API 与源码实现解析OpenCloud 中 vendored 的 Finite State EntropyFSE熵编码原理、Go API 与源码实现解析 Finite Sta后端微服务存储认证鉴权上一篇如何快速掌握AI动画生成ComfyUI-AnimateDiff-Evolved终极指南下一篇深度解析AI动画生成技术ComfyUI-AnimateDiff-Evolved高级实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考