JPEGJoint Photographic Experts Group是一种广泛使用的有损图像压缩格式。一、文件结构总览JPEG 文件以SOIStart of Image标记开始以EOIEnd of Image标记结束。中间由一系列标记段Marker Segment组成。SOI 起始标记 → 各类参数段(APP0/APP1/DQT/DHT/SOF/SOS...) → 压缩图像数据 → EOI 结束标记 ┌─────────────────────────────────────────┐ │ SOI (0xFFD8) 2 bytes │ ├─────────────────────────────────────────┤ │ APP0 / APPn 标记段 可变长度 │ ├─────────────────────────────────────────┤ │ DQT (量化表) 可变长度 │ ├─────────────────────────────────────────┤ │ SOF (帧头) 可变长度 │ ├─────────────────────────────────────────┤ │ DHT (哈夫曼表) 可变长度 │ ├─────────────────────────────────────────┤ │ SOS (扫描开始) 图像数据 可变长度 │ ├─────────────────────────────────────────┤ │ EOI (0xFFD9) 2 bytes │ └─────────────────────────────────────────┘1.1 核心标记所有标记均以0xFF开头后跟一个标记字节。标记十六进制名称说明SOIFF D8Start of Image文件起始标记SOF0FF C0Start of Frame (Baseline DCT)基线帧起始SOF2FF C2Start of Frame (Progressive DCT)渐进帧起始DHTFF C4Define Huffman Tables定义哈夫曼表DQTFF DBDefine Quantization Tables定义量化表DRIFF DDDefine Restart Interval定义重启间隔SOSFF DAStart of Scan扫描开始RSTnFF D0-D7Restart重启标记n0~7APPnFF E0-EFApplication-specific应用数据段COMFF FEComment注释段DNLFF DCDefine Number of Lines定义行数EOIFF D9End of Image文件结束标记二、核心标记解析2.1 SOI与EOI文件开发和结束标记仅仅作为标记无实际内容SOI: FF D8 // 仅2字节无长度字段EOI: FF D9 // 仅2字节无长度字段2.2 APP0 段JFIF 标记字节偏移 内容 长度 0-1 FF E0 2 bytes (标记) 2-3 length 2 bytes (段长度含此2字节) 4-8 JFIF\0 5 bytes (标识符) 9 version_major 1 byte 10 version_minor 1 byte 11 units 1 byte (0无单位, 1dpi, 2dpc) 12-13 Xdensity 2 bytes 14-15 Ydensity 2 bytes 16 Xthumb 1 byte (缩略图宽度) 17 Ythumb 1 byte (缩略图高度) 18-... thumbnail_data 3*X*Y bytes2B 标记FF E02B 段长 L5B 标识符JFIF\x001B 主版本号1B 次版本号如 1.021B 密度单位0 无单位1 像素 / 英寸2 像素 / 厘米2B X 密度2B Y 密度分辨率 DPI1B 缩略图宽1B 缩略图高剩余字节RGB 缩略图原始像素宽 × 高 ×3 字节无压缩2.3 DQT 段量化表0-1 FF DB 标记 2-3 length 段长度 4 Pq:Tq 1 byte - Pq (高4位): 精度 08bit, 116bit - Tq (低4位): 表号 0~3 5-... table_data 64 bytes (8bit) 或 128 bytes (16bit) (按 Zig-Zag 顺序)压缩核心8×8 量化矩阵决定画质高低。FF DB标记2B 段长1B 表编号 精度bit0~3 表 ID (0/1)bit708bit 量化116bit64B 量化矩阵Z 字形排列 8×8Zig-Zag 顺序64个 DCT 系数的读取顺序[ 0] [ 1] [ 5] [ 6] [14] [15] [27] [28][ 2] [ 4] [ 7] [13] [16] [26] [29] [42][ 3] [ 8] [12] [17] [25] [30] [41] [43][ 9] [11] [18] [24] [31] [40] [44] [53][10] [19] [23] [32] [39] [45] [52] [54][20] [22] [33] [38] [46] [51] [55] [60][21] [34] [37] [47] [50] [56] [59] [61][35] [36] [48] [49] [57] [58] [62] [63]2.4 SOF0 段帧起始0-1 FF C0 标记 2-3 length 段长度 4 precision 1 byte (通常8) 5-6 height 2 bytes 7-8 width 2 bytes 9 num_components 1 byte (1灰度, 3YCbCr, 4CMYK) 10-... components 3 bytes × num_components - C_i (component ID) - H_i:V_i (水平:垂直采样因子, 各4位) - T_q_i (使用的量化表号)定义图像尺寸、通道、采样格式解码必须参数FF C02B 段长1B 采样精度通常 8 位2B 图像高度 H大端2B 图像宽度 W大端1B 通道数量1 灰度图3YCbCr 彩色每组通道参数3 通道循环 3 次1B 通道 ID1Y 亮度2Cb 蓝色差3Cr 红色差高 4 位垂直采样因子 V低 4 位水平采样因子 H 例0x22 H2 V2 → Y4:2:0 标准采样2.5 DHT 段哈夫曼表0-1 FF C4 标记 2-3 length 段长度 4 Tc:Th 1 byte - Tc (高4位): 类型 0DC, 1AC - Th (低4位): 表号 0~3 5-20 L[1..16] 16 bytes (各长度码字的数量) 21-... V[..] ΣL bytes (按长度分组的符号值)存储熵编码用的霍夫曼码表分 DC直流低频、AC交流高频表亮度 / 色度各一套。FF C42B 段长1B 参数bit40 (DC)/1 (AC)bit0~3 表 ID (0/1)16B每个值代表码字长度对应码数1 位码多少个、2 位码多少个…后续 N 字节霍夫曼码字对应符号表2.6 SOS 段扫描开始0-1 FF DA 标记 2-3 length 段长度 4 num_components 1 byte (扫描中的分量数) 5-... components 2 bytes × num_components - Cs (component selector) - Td:Ta (DC表:AC表, 各4位) N0 Ss 1 byte (系数起始位置) N1 Se 1 byte (系数结束位置) N2 Ah:Al 1 byte (高位:低位比特位置) ┌───────────────────────────────┐ │ 压缩图像数据熵编码流 │ │ (紧接在 SOS 段之后) │ └───────────────────────────────┘参数配置完成后该段结束元数据后面就是压缩二进制像素流FF DA2B 段长1B 通道数 NN 组通道参数通道 ID (DC 表 ID4 | AC 表 ID)3B 固定参数基线 JPEG 恒为00 3F 00三、编码流程原始图像 (RGB)↓颜色空间转换 → YCbCr↓色度子采样 (4:4:4 / 4:2:2 / 4:2:0)↓分块 (8×8 宏块)↓电平偏移 (减去 128)↓DCT 变换 (离散余弦变换)↓量化 (除以量化表系数)↓Zig-Zag 扫描 → 一维序列↓DC 系数差分编码 (DPCM)↓AC 系数游程编码 (RLE)↓哈夫曼编码 (熵编码)↓字节填充 / 标记插入↓JPEG 文件DC 系数编码对相邻块的 DC 系数取差值DPCM然后确定差值的类别SIZE所需比特数用哈夫曼编码编码 SIZE附加 SIZE 位的幅度值AC 系数编码对 63 个 AC 系数按 Zig-Zag 顺序处理对每组 (RUN, SIZE/LEVEL)RUN连续零的个数 (0~15)SIZE非零值所需比特数LEVEL非零值的幅度特殊标记EOB (00)块结束后续全零ZRL (F0)16 个连续零(RUN, SIZE) 组合用哈夫曼编码LEVEL 用附加位