JPEG文件格式

JPEG文件通常以FFD8头部标识，以FFD9作为结束标识，在文件中以FF表示一个段的开头，后跟标识信息表示段的内容，再之后是两字节的数表示段的长度

编码过程

离散变换和量化

JPEG在处理图像之前将图片划分为8x8的小块来进行处理（这样的小块被称为最小编码单元），在处理的时候需要将像素值的范围进行修改，使得值的范围在$[-127, 128]$之间，未进行处理的范围在$[0, 255]$，使得像素值以0为中心，便于利用离散余弦变换。离散余弦变换把离散的数据变成多个余弦信号的组合。

二维DCT变换

$$F(u,v) = c(u)c(v)\sum_{i = 0}^{N - 1}\sum_{J = 0}^{N - 1}f(i, j)cos[\frac{(i + 0.5)\pi}{N}]cos[\frac{(j + 0.5)\pi}{N}]$$
$$c(x) = \begin{cases} \sqrt{\frac{1}{N}}, x = 0 \\ \sqrt{\frac{2}{N}}, x \neq 0 \\ \end{cases}$$

$$U=\frac{1}{2}\begin{bmatrix} \frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}} \\ cos\frac{\pi}{16} & cos\frac{3\pi}{16} & cos\frac{5\pi}{16} & cos\frac{7\pi}{16} & cos\frac{9\pi}{16} & cos\frac{11\pi}{16} & cos\frac{13\pi}{16} & cos\frac{15\pi}{16} \\ cos\frac{2\pi}{16} & cos\frac{6\pi}{16} & cos\frac{10\pi}{16} & cos\frac{14\pi}{16} & cos\frac{18\pi}{16} & cos\frac{22\pi}{16} & cos\frac{26\pi}{16} & cos\frac{30\pi}{16} \\ cos\frac{3\pi}{16} & cos\frac{9\pi}{16} & cos\frac{15\pi}{16} & cos\frac{21\pi}{16} & cos\frac{27\pi}{16} & cos\frac{33\pi}{16} & cos\frac{39\pi}{16} & cos\frac{45\pi}{16} \\ cos\frac{4\pi}{16} & cos\frac{12\pi}{16} & cos\frac{20\pi}{16} & cos\frac{28\pi}{16} & cos\frac{36\pi}{16} & cos\frac{44\pi}{16} & cos\frac{52\pi}{16} & cos\frac{60\pi}{16} \\ cos\frac{5\pi}{16} & cos\frac{15\pi}{16} & cos\frac{25\pi}{16} & cos\frac{35\pi}{16} & cos\frac{45\pi}{16} & cos\frac{55\pi}{16} & cos\frac{65\pi}{16} & cos\frac{75\pi}{16} \\ cos\frac{6\pi}{16} & cos\frac{18\pi}{16} & cos\frac{30\pi}{16} & cos\frac{42\pi}{16} & cos\frac{54\pi}{16} & cos\frac{66\pi}{16} & cos\frac{78\pi}{16} & cos\frac{90\pi}{16} \\ cos\frac{7\pi}{16} & cos\frac{21\pi}{16} & cos\frac{35\pi}{16} & cos\frac{49\pi}{16} & cos\frac{63\pi}{16} & cos\frac{77\pi}{16} & cos\frac{91\pi}{16} & cos\frac{105\pi}{16} \\ \end{bmatrix}$$

编码&压缩

Zig-Zag

$$\begin{bmatrix} 15 & 14 & 10 & 9 \\ 13 & 11 & 8 & 0 \\ 12 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 \end{bmatrix}$$

$$\begin{bmatrix} 15 & 14 & 13 & 12 &11 & 10 & 9 & 8 &0 & …… & 0 \end{bmatrix}$$

行程编码和增量编码

$$\begin{bmatrix} 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \end{bmatrix}$$

$$\begin{bmatrix} 0 & 8 \end{bmatrix}$$

$$\begin{bmatrix} 10 & 11 & 12 & 13 & 10 & 9 \end{bmatrix}$$

$$\begin{bmatrix} 10 & 1 & 2 & 3 & 0 & -1 \end{bmatrix}$$

In JPEG, every DC value in a DCT coefficient matrix is delta encoded relative to the DC value preceding it. This means that if you change the very first DCT coefficient of your image, the whole image will get screwed up but if you modify the first value of the last DCT matrix, only a very tiny part of your image will be affected. This is useful because the first DC value in your image is usually the most varied and by applying the Delta encoding we bring the rest of DC values close to 0 and that results in better compression in the next step of Huffman Encoding.

​ ——《Understanding and Decoding a JPEG Image using Python》

哈夫曼编码

FF C4表示哈夫曼表的开始，00 4B表示长度，随后跟的10表示类型，属于AC表的0号表

1 2 00 0x00
2 2 01 0x01
3 3 100 0x02
4 3 101 0x11
…… …… …… ……

(咕咕咕)

参考文章

Understanding and Decoding a JPEG Image using Python

Let’s Write a Simple JPEG Library, Part-II: The Decoder