研究.jpg图片马赛克问题

前奏

上次做了那个CTFBlink之后,对.jpg图片挺好奇的,于是准备来研究一下

jpg图片对比

在这里插入图片描述

jpg图片格式详解

JPEG图片格式组成部分:SOI(文件头)+APP0(图像识别信息)+DQT(定义量化表)+SOF0(图像基本信息)+DHT(定义Huffman表)+DRI(定义重新开始间隔)+SOS(扫描行开始)+EOI(文件尾)

JPEG文件的每个段都一定包含两部分一个是段的标识,它由两个字节构成:第一个字节是十六进制0xFF,第二个字节对于不同的段,这个值是不同的。
在这里插入图片描述
紧接着的两个字节存放的是这个段的长度(除了前面的两个字节0xFF和0xXX,X表示不确定。它们是不算到段的长度中)。

段的一般结构

名称字节数数据说明
段标识1FF每个新段的开始标识
段类型1类型编码(称作“标记码”)
段长度2包括段内容和段长度本身,不包括段标识和段类型
段内容<=65533字节

段类型

段类型标记码说明
SOID8文件头
EOID9文件尾
SOF0C0帧开始(标准 JPEG)
SOF1C1同上
DHTC4定义Huffman表(霍夫曼表)
SOSDA扫描行开始
SOSDB定义量化表
DRID0定义重新开始间隔
APP0E0定义交换格式和图像识别信息
COMFE注释

说明:有的文章也将DNL段(标记码=DC,定义扫描行数)列为必须段

PS:段类型有30种,但只有10种是必须被所以程序识别的,其它的类型都可以忽略

SOI文件头

JPEG文件的开始2个字节都是FF D8这是JPEG协议规定的

名称字节数
段标识1FF
段类型1D8

也就是这两个字节构成了JPEG文件头
在这里插入图片描述

APP0图像识别信息

APP0(图像识别信息)

名称字节数说明
段标识1FF
段类型1E0
段长度20010如果有RGB缩略图就=16+3*n(以下为段内容)
交换格式54A46494600“JFIF”的ASCII码
主版本号1
次版本号1
密度单位10=无单位;1=点数/英寸;2=点数/厘米
X像素密度2水平方向的密度
Y像素密度2垂直方向的密度
缩略图X像素1缩略图水平像素数目
缩略图Y像素1缩略图垂直像素数目
(如果“缩略图X像素”和缩略图Y像素的值均>0,那么才有下面的数据)
n=缩略图像素总数=缩略图X像素*缩略图Y像素
  1. JFIF是JPEG File Interchange Forma的缩写,即JPEG文件交换格式,另外还有TIFF等格式,很少用
  2. “如果有RGB缩略图就=16+3*n”是什么意思呢?比如说“缩略图X像素”和“缩略图Y像素”的值均为48,就表示有一个48*48像素的缩略图(n=48*48),缩略图是24位真彩位图,用3个字节来表示一个像素,所以共占有3*n个字节。但大多数JPG文件都没有这个缩略图

在这里插入图片描述

  1. 图像识别信息头:2个字节 FF E0
  2. 段长度:00 10 =>16个字节
  3. 交换格式:4A 46 49 46 00=>此处为’JFIF’,一般我们用的都是JFIF的jpeg交换格式,但是也有TFIF的jpeg的交换格式,如果camera sensor直接输出的是jpeg图片,那么在其sensor寄存器可以设置使用JFIF还是TFIF
  4. 主版本号和次版本号一共2个字节:01 01 =>说明主版本号和次版本号都为1
  5. 单位密度1个字节:00=>表示此处使用的是无单位
  6. X像素密度2个字节:00 01 =>水平像素密度是1
  7. Y像素密度2个字节:00 01 =>水平像素密度是1
  8. 缩略图X像素:00=>没有缩略图
  9. 缩略图Y像素:00=>没有缩略图
  10. RGB缩略图:此处没有缩略图,所以是空的

DQT定义量化表

DQT(定义量化表)

名称字节数说明
段标识1FF
段类型1DB
段长度243其值=3+n(当只有一个QT时)(以下为段内容)
QT信息10~3:QT号 ;4~7位:QT精度(0=8bit,1字节;否则=16bit,2字节)
QTnn=64*QT精度的字节数

说明:

  1. JPEG文件一般有2个DQT段,为Y值(亮度)定义1个,为C值(色度)定义1个
  2. 一个DQT段可以包含多个QT,每个都有自己的信息字节

此处有两个DQT数据,第一个是亮度的,第二个是色度的
在这里插入图片描述

  1. 定义量化表的头2个字节:FF DB
  2. 段长度2个字节: 00 43=>3(段长度2个字节,QT信息1个字节)+QT量化表的长度,此处QT量化表的长度是64
  3. QT信息1个字节:00=>0-3位是QT号,4-7位QT精度,此处是0,所以精度是8bit,即1个字节
  4. QT量化表:这个长度时根据QT信息确定的,上面QT精度为8bit,所以此处是64*1=64个字节

在这里插入图片描述

  1. 定义量化表的头2个字节:FF DB
  2. 段长度2个字节: 00 43=>3(段长度2个字节,QT信息1个字节)+QT量化表的长度,此处QT量化表的长度是64
  3. QT信息1个字节:01=>0-3位是QT号,即QT号是1,4-7位QT精度,此处是0,所以精度是8bit,即1个字节
  4. QT量化表:这个长度时根据QT信息确定的,上面QT精度为8bit,所以此处是64*1=64个字节

SOF0图像基本信息

SOF0(图像基本信息)

名称字节数说明
段标识1FF
段类型1C0
段长度2其值=8+组件数量*3 (以下为段内容)
样本精度18每个样本位数(大多数软件不支持12和16)
图片高度2
图片宽度2
组件数量131=灰度图,3=YCbCr/YIQ,4=CMYK 彩色图(以下每个组件占用3个字节)
组件 ID11=Y,2=Cb,3=Cr,4=I,5=Q
采样系数10-3位:垂直采样系数 ;4-7位:水平采样系数
量化表号1

说明:

  1. JPEG大都采用yCrCb色彩模型(y表示亮度,Cr表示红色分量,Cb表示蓝色分量),所以组件数量一般=3
  2. 样本就是单个像素的颜色分量,也可理解为一个样本就是一个组件
  3. 采样系数是实际采样方式与最高采样系数之比,而最高采样系数一般=0.5(分数表示为1/2)。比如说,垂直采样系数=2,那么2*0.5=1,表示实际采样方式是每个点采一个样,也就是逐点采样;如果垂直采样系数为1,那么:1*0.5=0.5(分数表示为1/2),表示每两个点采一个样

在这里插入图片描述

  1. 图像基本信息:FF C2(不知道为什么我这里是C2,我查到的是C0)
  2. 段长度2个字节:00 11 =>17=8+3*3,说明组件数量有3个
  3. 样本精度1个字节:08,每个样本的信息是8bit
  4. 样本高度2个字节:01 84 =>388图片高度与实际一致
  5. 样本宽度2个字节:02 6C =>620图片宽度与实际一致
    在这里插入图片描述
  6. 组件数量1个字节:03=>代表YCbCr彩色图,有三个组件分别是Y,Cb,Cr
  7. 每个组件占用3个字节:第一个字节是组件ID,第二个字节是采样系数,第三个字节是量化表号

此处是:

  1. 01 11 00=>Y组件,垂直采样系数和水平采样系数都是1,量化标号是0
  2. 02 11 01=>Cb组件,垂直采样系数和水平采样系数都是1,量化标号是1
  3. 03 11 01=>Cr组件,垂直采样系数和水平采样系数都是1,量化标号是1

//此处可知三个组件都是隔点采样(标准的YUV422数据:Y采样是逐点采样,CbCr都是隔点采样)

DHT定义huffman表

DHT(定义Huffman表)

名称字节数说明
段标识1FF
段类型1DB
段长度2其值=19+n(当只有一个HT表时)(以下为段内容)
HT信息10-3:HT号;4位:HT类型,0=DC表,1=AC表;5-7位:必须=0
HT位表16这16个数的和应该<=256
HT值表nn=表头16个数的和

说明:

  1. JPEG文件里有2类Haffman表:一类用于DC(直流量),一类用于AC(交流量)。一般有4个表:亮度的DC和AC,色度的AC和DC。最多可有6个
  2. 一个DHT段可以包含多个HT表,每个都有自己的信息字节
  3. HT表是一个按递增次序代码长度排列的符号表

在这里插入图片描述

  1. 定义Huffman表头2个字节:FF C4
  2. 段长度2个字节:00 1D=>29=19(段长度2字节+HT信息1个字节+HT位表16个字节)+10(这个数代表HT表有10字节)
  3. HT信息1个字节:0-3位是HT号,4位是HT类型(0=DC表,1=AC表),5-7位必须为0。HT号位0,此表为DC表
  4. HT位表16个字节:这10个数字值和小于等于256
01 00 02 02 03 01 01 00 00 00 00 00 00 00 00  00=>16个字节,加起来10(此处和段长度是相匹配的),说明HT表有10字节
  1. HT值表:
00 07 08 01 06 02 04 05 09 03

在这里插入图片描述

  1. 定义Huffman表头2个字节:FF C4
  2. 段长度2个字节:00 1C=>28=19(段长度2字节+HT信息1个字节+HT位表16个字节)+9(这个数代表HT表有9字节)
  3. HT信息1个字节:0-3位是HT号,4位是HT类型(0=DC表,1=AC表),5-7位必须为0。HT号位1,此表为AC表
  4. HT位表16个字节:这10个数字值和小于等于256
01 00 01 05 01 01 00 00 00 00 00 00 00 00 00 00=>16个字节,加起来9(此处和段长度是相匹配的),说明HT表有9字节
  1. HT值表:
 00 01 02 03 04 05 07 06 08

SOS扫描行开始(图像数据开始)

SOS扫描行开始

名称字节数说明
段标识1FF
段类型1DA
段长度2000C其值=6+2*扫描行内组件数量 (以下为段内容)
扫描行内组件数量13必须>=1,<=4(否则错误),通常=3(以下每个组件占用2字节)
组件ID11=Y,2=Cb,3=Cr,4=I,5=Q
Huffman表号10-3位:AC表号(其值=0……3);4-7位:DC表号(其值=0……3)
剩余3个字节3最后3个字节用途不明,忽略

说明:

  1. 紧跟SOS段后的是压缩的图像数据(一个个扫描行),数据存放顺序是从左到右,从上到下(经过压缩算法处理过后的)。

在这里插入图片描述

  1. 扫描行开始的头:FF DA
  2. 段长度2个字节:00 0C=>12=6(2个字节的段长度+1个字节扫描行内组件数量+3个字节的剩余位)+2*3(扫描行内组件数量,每个组件2个字节)
  3. 扫描行内组件数量,1个字节:03=>代表组件数量数3
  4. 每个组件占用2个字节:
    第一个字节是组件ID(1=Y,2=Cb,3=Cr,4=I,5=Q);第二个字节0-3AC表,4-7位是DC表。表号的值是0-3

01 00=>Y组件,AC表号是0,DC表号是0
02 10=>Cb组件,AC表号是0,DC表号是1
03 10=>Cr组件,AC表号是0,DC表号是1

EOI扫描行结尾

名称字节数
段标识1FF
段类型1D9

这两个字节构成了JPEG文件尾
在这里插入图片描述

其他段

COM(注释)

名称字节数说明
段标识1FF
段类型1FE
段长度2其值=注释字符的字节数+2
段内容注释字符

说明:有的JPEG文件没有这个段

DRI(定义重新开始间隔)

名称字节数说明
段标识1FF
段类型1DD
段长度24(以下为段内容)
开始间隔2n复位标记的间隔距离

说明:

  1. 开始间隔表示在压缩数据流中,每隔n个MCU块就有一个RST标记,RST标记将Huffman的解码数据流复位,DC也重新从0开始,因此,RST标记是一种复位标记
  2. RST标记是一种特殊的段,它只具有段标识和段类型(长度=2字节),但它不是独立的段,只能穿插在数据流中(文件头和文件尾也只有段标识和段类型,却都是独立的段)
  3. RST标记共有8个(RST0-RST7),从RST0起开始使用,然后是RST1……RST7,再从RST0重复
  4. RST标记的标识码是FFD0-FFD7,对应RST0-RST7
  5. 补充:这个不是必须段,很多JPEG都没有

JPEG压缩编码实例

DC是指直流系数,是8X8个像素的平均值;AC是交流系数,是8X8个像素的其它值,压缩数据的排列方式是:亮度DC,AC,色差DC,AC,色差DC,AC

  1. 每个分量如Y分量(DC+AC)完成后,如果还剩下位数,应该舍弃,后面的Cb是从下一个字节重新计算
  2. 如果编码到后面没有压缩数据了,后面实际编码数据用0填充
  3. 如果编码已经完成,那么剩余压缩数据用1填充

红色色块编码

在这里插入图片描述

51 			45 			00 			14 				51 				45 				00 			7F
01010001	01000101	00000000	00010100		01010001		01000101		00000000	01111111

计算Y亮度分量=>

0101-0001 01-0001-01

首先有一个DC系数需要计算出来
DC亮度

计算第一个色差分量 =>

在这里插入代码片

黑色色块编码

在这里插入图片描述

28 				A2 				8A 			00 			28 				A2 				8A 				00
00101000		10100010		10001010	00000000	00101000		10100010		10001010		00000000				

对比结果

开头:

在这里插入图片描述

结尾

在这里插入图片描述

省略部分分析

至F0行开始就是SOS扫描行,一直往下扫描,被省略的是B30行~4E60行,全是扫描行数据(也就是说全是图像数据),且加密数据,
所以我们尝试一下SOS扫描行开始段结束这里,加一个扫描行结束标志FF D9(那么图片肯定是可以显示出来的(也就是说可以打开),因为它的格式框架是正确的,只是没有内容而已)
在这里插入图片描述
在这里插入图片描述
然后保存
在这里插入图片描述
猜想正确,直接连马赛克都没了。所以的话,马赛克出现的原因只是因为绘图未完整而已(至于怎么个未完整法,因为是加密数据………………)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寻梦&之璐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值