/jpeg_tutorial

跟我寫 JPEG 解碼器 (Write a JPEG decoder with me)

Primary LanguageRust

跟我寫 JPEG 解碼器

緣起

幾年前曾用 C++ 寫過一次 JPEG 解碼器,還記得當時網路上對 JPEG 格式的介紹都雜亂無章、少東缺西,而標準書爲求完整嚴謹,寫的是又臭又長。就沒有讓我趕快寫完作業的法子嗎?最後我在 github 上撈到了一份 python 寫的解碼器,透過追蹤這份程式碼,才好不容易地把網路文章寫的不清楚的地方弄懂了。

我在寫作本文時,特地又搜尋了一次網路文章,發現這幾年確實出現了幾篇比較好的文章,但再繼續深挖,就會發現講解 JPEG 的中文文章萬變不離其宗,都是從這篇 JPEG 圖像解碼方案修修補補來的,在理論的深度以及論述的清晰度都略有不足,因此嘗試挑戰看看,能否用自己的方式將 JPEG 講解的更清楚。但有些前人的例子非常不錯,會註明出處後繼續沿用。

本文的目的是:希冀讀者只要跟着本文的腳步,就能夠最快的打造出自己的 JPEG 解碼器。此外,我也會在邊寫作本文邊再次實作 JPEG 解碼器的過程中,實作一些能協助除錯的小工具,一併開源讓讀者使用,解碼器的源碼也會盡量保持可讀性,可供讀者直接參考。

如果還有時間,我也會嘗試撰寫一份 JPEG 的理論基礎,畢竟,能夠實作算法,並不代表理解了算法的原理,我當年便是如此,寫完了,但卻感覺沒學到什麼。而理論方面的文章還很缺乏,我願做先鋒,雖千萬人吾往矣。

章節說明

爲了便於閱讀,爲了讓讀者有種過關斬將,一直有進度的感覺,我把整套解碼過程切割成五個章節,還有附錄講解 JPEG 的理論基礎、優化技巧。

閱讀數學式

github 並不支援在 markdown 中寫數學式,建議 clone 本專案之後,以 typora (在 typora 的偏好設定中開啓行內數學式) 或是其他 markdown 閱讀軟體來閱讀,會有更佳的體驗。

前置準備

下載程式碼

git clone https://github.com/MROS/jpeg_tutorial

安裝

cd jpeg_tutorial
cargo install --path .

cargo install 會將編譯出的執行檔 jpeg_tutorial 放進 ~/.cargo/bin 之中,請確認 ~/.cargo/bin 已經在 $PATH 裡。

執行

轉檔爲 ppm 格式

ppm 檔的預設檔名爲 out.ppm

jpeg_tutorial <jpeg_path> ppm

不加子命令,預設效果也是轉換爲 ppm

jpeg_tutorial <jpeg_path>

打印各區段數據

jpeg_tutorial <jpeg_path> reader

僅打印標記碼

jpeg_tutorial <jpeg_path> marker

打印指定 mcu 在解碼過程的各階段狀態

jpeg_tutorial <jpeg_path> mcu <縱座標> <橫座標>

假設有一張圖片高度上有 8 個 mcu 、寬度上有 12 個 mcu ,用

jpeg_tutorial <jpeg_path> mcu 7 11

來得到最右下角的 mcu 各階段狀態,注意到索引從 0 開始。