Deflate内部实现(LZ77无损压缩算法)超详细图解算法版~

无损压缩算法

  • 第一阶段:重复消除 — LZ77无损压缩算法
    • 算法介绍
      • 举例
      • 压缩算法思路
      • 图解压缩过程
  • 第二阶段:位减少
    • huffman
    • 位减少

概览

  • Gzip
    • Deflate 编码(LZ77+哈夫曼)
  • Brotli
    • LZ77+哈夫曼+二阶上下文建模

Deflate 分两个阶段压缩数据:重复消除位减少

第一阶段:重复消除 — LZ77无损压缩算法

算法介绍

基于字典的无损压缩算法,它搜索重复的未压缩序列并用引用指针替换它们。

引用指针由 2 个元素定义:

  • offset距离(或偏移量):原始未压缩数据中出现的第一个现有字节的相对返回。
  • Length:重复的字节长度。

当对序列进行压缩的时候,采用 “滑动窗口” 算法,
结构如下:

  • 查找缓冲区(Search buffer),也称字典(已编码部分)
  • 先行缓冲区(Look ahead buffer),包括即将进行编码序列的一部分。每次读取数据的时候,先把一部分数据预载入前向缓冲区。为移入滑动窗口做准备。

由于缓冲区具有固定的长度,所以,当算法(编码器)在运行时候,它看起来像在文件中“滑动”,所以这个缓冲区被称为“滑动窗口”。

滑动窗的尺寸是影响压缩性能的关键因素之一。如果滑动窗口太小,则压缩器可能会发现较少的重复数据序列,结果,压缩文件的大小将更大。如果滑动窗口太大,则压缩器可能需要花费更长的时间来查找重复的数据序列,因此压缩速度将变慢。
在这里插入图片描述

要使用 LZ77 压缩算法:

  1. 将编码位置设置为输入流的开头。
  2. 在查找缓冲区的窗口中找到最长的匹配项。
  3. 如果找到匹配,则输出指针 P。将编码位置(和窗口)向前移动 L个字节。
  4. 如果未找到匹配项,则输出空指针和先行缓冲区中的第一个字节。将编码位置(和窗口)向前移动一个字节。
  5. 如果先行缓冲区不为空,则返回步骤 2。

主要逻辑 :
通过先行缓冲区预读取数据,然后向字典中移入, 不断搜索字典中与先行缓冲区连续相匹配的最长序列,然后输出metadata标记。

举例

以微软的例子来理解算法:微软介绍:LZ77压缩算法

Input stream

Position    1    2    3    4    5    6    7    8    9
Byte        A    A    B    C    B    B    A    B    C

Output 期望压缩后得到的结果:
在这里插入图片描述

压缩后怎么能读取到原文呢?

答:需要将output进行解码,如:
(0,0)‘X’:直接推入X
(o,l):找到offset=o的位置,往后复制l个字符
在这里插入图片描述

看来最重要的一环就是如何压缩啦!让我们一起看看这个算法的思路和图解吧~

压缩算法思路

AABCBBABC串,将重复的子串用指针进行替换,
对于其中的每个元素 x 有两种情况:
     1. 前文没有任何重复的子串:输出(0,0)x
     2. 在前文能找到重复的子串:输出(offset = x和匹配子串的的距离,length = 匹配子串的长度)

图解压缩过程

字符序列移动方向:从右往左

简称:

  • buffer区:先行缓存区(未编码),这是需要匹配的字符串
  • Dictionary:查找缓存区(已编码),用来匹配buffer的字典区域
  1. 初始字符串从右往左滑动,直至占满所有buffer区,如图1
    在这里插入图片描述
                    (图1)
    在这里插入图片描述

  2. 开始遍历 图1 buffer的第一个字符’A’,因Dictionary空,未匹配到’A’ => 往左移一格(如图2),输出(0,0)A。
    (offset = A无匹配子串,距离=0,length:0,无重复子串)在这里插入图片描述                (图2)
    在这里插入图片描述

  3. 遍历 图3 buffer第一个字符"A",在Dictionary找到"A",未超过buffer黄色长度,往后遍历到编码"AB",Dictionary没有匹配到“AB”字符串,于是只编码"A",输出(1, 1)。
    在这里插入图片描述
                    (图3)

    图4,匹配长度为1,所以字符串向左偏移一个单位:
    在这里插入图片描述
                    (图4)
    在这里插入图片描述

  4. 匹配buffer区第一个字符’B’,Dictionary内未匹配,同步骤1,输出(0,0)B,左移一格。

  5. 匹配buffer区第一个字符’C’,Dictionary内未匹配,同上,输出(0,0)C,左移一格,如 图5
    在这里插入图片描述
                    (图5)
    在这里插入图片描述

  6. 匹配 图6 buffer区第一个字符’B’,offset('B’与Dictionary中匹配的’B’的距离)=2,两个查找指针同时往后移1(如图6),比较'C'vs'B'不匹配,终止,length=1,输出(2,1)
    在这里插入图片描述
                    (图6

    得到结果:
    在这里插入图片描述
                    (图7)
    在这里插入图片描述

  7. 匹配 图7 buffer区第一个字符’B’,Dictionary匹配到‘B’,分别是offset=1和offset=3,但offset=3下一字节'C'vs'A'不匹配,就近原则选择offset=1,length=1,输出(1,1)。
    在这里插入图片描述
                    (图8)
    此时已编码序列长度大于Dictionary区,有序列滑出了窗口,如图8
    在这里插入图片描述

  8. 匹配 图8 BUFFER第一个字符 ‘A’,在DICTIONARY匹配到,offset=5,往后遍历直到匹配"ABC",length=3,此时不能再往后编码否则超过BUFFER区域长度,故输出(5, 3),往左移动3格,如图:
    在这里插入图片描述
    在这里插入图片描述

第二阶段:位减少

huffman

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通过哈夫曼树,我们可以将原本需要120bit(15*8)的位减少到 28bit

位减少

范式huffman树:在普通huffman树的基础上只要保存编码位长,利用位长反推编码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/723859.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

构建高效的大数据量延迟任务调度平台

目录 引言系统需求分析系统架构设计 总体架构任务调度模块任务存储模块任务执行模块 任务调度算法 时间轮算法优先级队列分布式锁 数据存储方案 关系型数据库NoSQL数据库混合存储方案 容错和高可用性 主从复制数据备份与恢复故障转移 性能优化 水平扩展缓存机制异步处理 监控与…

宏观必读:数智化、气候能源、多极化趋势并存,如何获得转型性增长?

关键词速读: 双转型——创新主导的 “新质生产力”正加速推动中国产业的数字化和绿色低碳“双转型”。 双引擎——企业借助“技术创新”和“生态创新”两大引擎,乘势而上,赢得未来机遇。 生成式 AI 与大模型爆发式发展正在引发计算、开发、交…

C语言——扫雷小游戏

扫雷小游戏: 游戏最终效果: 1.先写一下游戏开始的简单界面。 用一个函数来写一下 void menu() {printf(" ---------------------------- \n");printf("| 1.play |\n");printf("| 0.exit …

QT 的文件

QT 和C、linux 一样,也有自带的文件系统. 它的操作和C、c差不多,不过也需要我们来了解一下。 输入输出设备类 QObject 有一个子类,名为 QIODevice 类,如其名字,该类是管理所有输入输出设备的类。 比如文件、网络套…

软件测试技术(一):软件测试流程

软件测试流程 软件测试流程如下: 测试计划测试设计测试执行 单元测试集成测试确认测试系统测试验收测试回归测试验证活动 测试计划 测试计划由测试负责人来编写,用于确定各个测试阶段的目标和策略。这个过程将输出测试计划,明确要完成的测…

Excel如何设置自动更新的固定选项

日常工作中你是否想要某数据列设置固定选项,如人力组、财务组、综合组、业务组等,可用“数据验证”实现,如后期新增选项“党建组”,该如何快速处理? 今天刘小生分享“超级表数据验证”方式,只实现固定选项…

Java 项目学习(初始化项目)

后端工程基于 maven 进行项目构建,并且进行分模块开发 参考:Spring或Spring Boot项目目录结构划分和代码分层 1、了解项目的整体结构 sky-take-out maven 父工程,统一管理依赖版本,聚合其他子模块 sky-common 子模块&#xff0c…

Maven私服批量上传pom和jar实操

Maven私服上传pom和jar实操-CSDN博客 Maven私服上传jar实操_maven fakepath-CSDN博客 之前写过两篇向maven私服上传jar的操作,看到阅读量还可以,觉得应该有很多人有这个需求,所以这次再放一个大招,通过批量的方式向私服传jar和p…

2024最新版:C++用Vcpkg搭配VS2022安装matplotlib-cpp库

matplotlib-cpp是一个用于在C中使用matplotlib绘图库的头文件库。它提供了一个简单的接口,使得在C中创建和显示图形变得更加容易。这个库的灵感来自于Python的matplotlib库,它使得在C中进行数据可视化变得更加便捷。 matplotlib-cpp允许在C中使用类似Py…

【R语言】数据可视化分析和统计检验——线性和线性混合效应模型

R语言数据可视化分析和统计检验 写在前面1、数据读取及分析2、组间均值和标准差统计分析3、图像数据探索3.1 图像绘制(查看是否存在极端数据,以及数据分布情况)3. 2 数据标准化(Z-scores)3.3 绘制数据相关性 4、ggplot…

杭州电子科技大学2024年成人高等继续教育招生简章

杭州电子科技大学,作为一所享有盛誉的高等学府,始终致力于为社会培养优秀的人才。2024年,学校敞开大门,为广大有志于进一步提升自身学识与技能的成年人提供了难得的机会——成人高等教育招生。 此次招生不仅彰显了杭州电子科技大…

轻量级的数据交换格式JSON (JavaScript Object Notation)介绍

什么是JSON? JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式,它属于JavaScript的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 JSON具有易读性&…

FFmpeg+ZLMediaKit 超低延时推流

FFmpeg超低延时推流命令 ffmpeg -rtbufsize 4M -i rtsp://admin:abcd1234192.168.2.162:554/h264/ch1/main/av_stream \-c:v libx264 -preset ultrafast -tune zerolatency -x264-params keyint30:min-keyint30:scenecut0 -g 30 \-c:a aac -b:a 128k -ar 44100 -ac 2 -strict …

微型导轨的摩擦系数分析!

微型导轨的摩擦力主要包括滑动摩擦力和滚动摩擦力,摩擦系数是一个关键参数,它决定了滑块在导轨上运动时所受到的摩擦力大小,摩擦系数越低,系统的运动效率和精度就越高,而微型导轨的摩擦系数是受多个因素影响的。 微型导…

【PL理论】(33) 类型系统:推导树证明 φ ⊢ e∶t | 继续定义关系:γ ⊢ e∶t

💬 写在前面:本章我们将讲解推导树证明,推导树实际上就是推理规则的应用。只要学会如何选择并应用适当的推理规则,证明就不是难事了。 目录 0x00 推导树证明 𝝓 ⊢ 𝒆 ∶ 𝒕 0x01 继续定义关…

振动分析-5-基于CNN的机械故障诊断方法

参考基于CNN的机械故障诊断方法 CNN之图像识别 预训练模型迁移学习(Transfer Learning) 基于卷积神经网络(CNN)的深度迁移学习在声发射(AE)监测螺栓连接状况的应用 参考基于CNN的机械故障诊断所面临的困难和…

护眼指南:精选适合学生写作业的台灯推荐

当前,近视问题在人群中愈发普遍,据2024年的统计数据显示,我国儿童青少年的总体近视率已高达52.7%。在繁重的学业压力下,学生的视力健康日益受到关注,近视背后潜藏着诸多眼部并发症的风险,包括但不限于视网膜脱离、视网…

ATFX汇市:英国5月核心CPI年率下降0.4百分点,GBPUSD不跌反涨

ATFX汇市:据英国统计局数据,英国5月核心CPI年率为3.5%,低于前值3.9%;英国5月名义CPI年率为2%,低于前值2.3%。核心CPI年率和名义CPI年率相比前值分别下降0.4个百分点和0.3百分点,意味着英国的通胀率仍处于快…

Nidhogg:一款专为红队设计的多功能Rootkit

关于Nidhogg Nidhogg是一款专为红队设计的多功能Rootkit,该工具的主要目的是为红队研究人员提供一个多合一的切易于使用的多功能Rootkit,并允许研究人员通过单个头文件来将其引入到自己的C2框架之中。 当前版本的Nidhogg支持任意版本的x64 Windows 10和…

Monaco Editor系列(八)插入自定义DOM、删除指定位置的单词、给特定单词着色

前言:人都不知道自己是谁,所以想让自己成为什么样的人,就多给自己说什么样的话。我爱学习!学习使我快乐!回顾一下上一篇文章的内容。还记得 Monaco Editor 的三个命名空间吗?分别是 editor、languages、wor…