JPEG解碼——(5)反量化和逆ZigZag變換
阿新 • • 發佈:2021-03-02
本篇是該系列的第五篇,承接上篇huffman解碼,介紹接下來的兩個步驟——反量化和逆zigzag變換,即IDCT前的兩個步驟。
需要說明的是,這兩個步驟可以顛倒,本人的實現是,先反量化,再逆ZigZag變換。
其實,這兩步不需要太多說明,無非是查表對資料進行scale和資料重排,為了完整性,還是介紹一下吧。
1. 反量化
先拿到兩個表,一個是解析檔案頭得到的量化表,另外一個是huffman解碼得到的重建的8x8的block表。如下:
如何操作?對應位置相乘,即得到的反量化表:
2. 逆ZigZag變換
反量化表dequantization table是由如下ZigZag方式掃描得到的(忽略數字,關注箭頭掃描方向):
因此,需要對該表進行恢復,得到:
如何操作?無非是查表,可以參考下面的程式碼實現:
1 static const uint8_t zigzag[64] = 2 { 3 0, 1, 5, 6, 14, 15, 27, 28, 4 2, 4, 7, 13, 16, 26, 29, 42, 5 3, 8, 12, 17, 25, 30, 41, 43, 6 9, 11, 18, 24, 31, 40, 44, 53, 7 10, 19, 23, 32, 39, 45, 52, 54, 8 20, 22, 33, 38, 46, 51, 55, 60, 9 21, 34, 37, 47, 50, 56, 59, 61, 10 35, 36, 48, 49, 57, 58, 62, 63 11 }; 12 13 // IZigZag 14 int JpegReZigZag(struct ABitReader *abr, struct jpegParam *param, int *dst_block, const int *src_block, bool dump) 15 { 16 for (int i=0; i<64; i++) { 17 dst_block[i] = src_block[zigzag[i]]; 18 } 19 20 if (dump) { 21 puts("----after rezigzag----"); 22 for (int i=0; i<64; i++) { 23 printf("%4d ", dst_block[i]); 24 if (i % 8 == 7) 25 puts(""); 26 } 27 puts(""); 28 } 29 30 return 0; 31 }