主頁 >  其他 > JPEG原理分析及JPEG解碼器的除錯

JPEG原理分析及JPEG解碼器的除錯

2021-06-10 09:58:56 其他

JPEG原理分析及JPEG解碼器的除錯

  • 一、實驗目的
  • 二、實驗內容
    • 1、JPEG編解碼原理
      • (1)零偏置電平下移
      • (2)8x8 DCT
      • (3)量化
      • (4)直流DC系數的DPCM編碼
      • (5)AC系數的Z字掃描
      • (6)Huffman編碼
        • ①DC系數的Huffman編碼
        • ②AC系數的Huffman編碼
    • 2、JPEG檔案格式
      • (1)Segment的組織形式
      • (2)JPEG的Segment Market
  • 三、實驗步驟
    • 0、程式準備
    • 1、運行JPEG解碼程式,并輸出可供YUVviewer觀看的YUV檔案
    • 2、程式除錯程序的理解
      • (1)理解程式設計的整體框架
      • (2)理解三個結構體的設計目的
        • ①`struct huffman_table`
        • ②`struct component`
        • ③`struct jdec_private`
      • (3)理解在視音頻編解碼除錯中TRACE的目的和含義
    • 3、輸出量化矩陣和Huffman碼表
      • (1)量化矩陣
      • (2)Huffman碼表
      • (3)輸出結果
  • 四、實驗結論

一、實驗目的

  1. 掌握JPEG編解碼系統的基本原理,
  2. 初步掌握復雜的資料壓縮演算法實作,并能根據理論分析需要實作所對應資料的輸出,

二、實驗內容

1、JPEG編解碼原理

在這里插入圖片描述
JPEG編碼程序如上圖所示,解碼是編碼的逆程序,下面以編碼為例進行分析,

(1)零偏置電平下移

  • 操作:先對8×8的像塊進行零偏置電平下移(Level Offset),即對于灰度級是2n的像素,通過減去 2n-1,將無符號的整數值變成有符號數,
  • 目的: 使像素的絕對值出現 3 位 10 進制的概率大大減少,
  • 對于n=8,即將0~255的值域,通過減去128轉換為值域在-128~127之間的值

(2)8x8 DCT

  • 將原始影像分為8x8的小塊, 每個block里有64個像素,
  • 將影像塊作為2維離散余弦變換DCT的輸入,最后得到DCT變換的輸出,如圖所示:
    在這里插入圖片描述

(3)量化

  • 因為人眼對亮度信號比對色差信號更敏感,因此使用了兩種量化表:亮度量化值和色差量化值,
  • 根據人眼的視覺特性(對低頻敏感,對高頻不太敏感)對低頻分量采取較細的量化,對高頻分量采取較粗的量化,
  • 如果原始圖象中細節豐富,則去掉的資料較多,量化后的系數與量化前差別較大,反之,細節少的原始圖象在壓縮時去掉的資料少些,量化后的系數與量化前差別較小, 在這里插入圖片描述

(4)直流DC系數的DPCM編碼

由于8×8影像塊經過DCT變換之后得到的DC直流系數有兩個特點:

  • 系數的數值比較大
  • 相鄰 8 × 8 影像塊的 DC 系數值變化不大:冗余

根據這個特點,JPEG演算法使用了差分脈沖調制編碼(DPCM)技術,對相鄰影像塊之間量化DC系數的差值DIFF進行編碼:
D I F F k = D C k ? D C k ? 1 DIFF_k=DC_k-DC_{k-1} DIFFk?=DCk??DCk?1?

(5)AC系數的Z字掃描

  • 由于經DCT變換后,系數大多數集中在左上角,即低頻分量區,因此采用Z字形按頻率的高低順序讀出,可以出現很多連零的機會,可以使用游程編碼,尤其在最后,如果都是零,給出EOB (End of Block)即可,
  • 然后,系數序列分組,將非零系數和它前面的相鄰的全部零系數分在一組內;每組用兩個符號表示 [(Run, Size), (Amplitude)]

Amplitude:表示非零系數的幅度值;
Run:表示零的游程即零的個數;
Size:表示非零系數的幅度值的編碼位數,

在這里插入圖片描述

(6)Huffman編碼

①DC系數的Huffman編碼

  • 對DIFF用Huffman編碼:分成類別,類似指數Golomb編碼,
    類別ID:一元碼編碼
    類內索引:采用定長碼
    在這里插入圖片描述
  • DC系數Huffman編碼舉例:
    在這里插入圖片描述

②AC系數的Huffman編碼

  • 在JPEG和MPEG編碼種規定:(run, level)表示連續run個0,后面跟值為level的系數,
  • 編碼時,run最大為15,用4位表示RRRR;level編碼類似DC,分成16個類別,用4位表示,SSSS表示類別號,再加上類內索引進行編碼,對(RRRR,SSSS)聯合用Huffman編碼;對類內索引采用定長編碼,
  • AC系數Huffman編碼舉例:在這里插入圖片描述

2、JPEG檔案格式

(1)Segment的組織形式

JPEG在檔案中以Segment的形式組織 ,它具有以下特點:

  • 均以0xFF開始,后跟1byte的Marker和2byte的Segment length(包含表示Length本身所占用的2byte,不含0xFF+Marker所占用的2byte);
  • 采用 Motorola序(相對于Intel序),即保存時高位在前,低位在后;
  • Data部分中,0xFF后若為0x00,則跳過此位元組不予處理,

(2)JPEG的Segment Market

在這里插入圖片描述

在這里插入圖片描述

三、實驗步驟

0、程式準備

遵循程式要求,在除錯屬性內設定好命令引數,

  • 第一個引數為要解碼的jpg檔案;
  • 第二個引數為功能選項,此處選擇yuv420p,即轉換為yuv420格式的檔案;
  • 第三個引數為輸出檔案,

在這里插入圖片描述

1、運行JPEG解碼程式,并輸出可供YUVviewer觀看的YUV檔案

觀察除錯解碼程式發現,Y、U、V分量輸出程序在如下所示的函式內,在//輸出yuv檔案后增加一段程式輸出YUV檔案,再次運行程式,

/**
 * Save a buffer in three files (.Y, .U, .V) useable by yuvsplittoppm
 */
static void write_yuv(const char* filename, int width, int height, unsigned char** components)
{
	FILE* F;
	char temp[1024];
	snprintf(temp, 1024, "%s.Y", filename);
	F = fopen(temp, "wb");
	fwrite(components[0], width, height, F);
	fclose(F);
	snprintf(temp, 1024, "%s.U", filename);
	F = fopen(temp, "wb");
	fwrite(components[1], width * height / 4, 1, F);
	fclose(F);
	snprintf(temp, 1024, "%s.V", filename);
	F = fopen(temp, "wb");
	fwrite(components[2], width * height / 4, 1, F);
	fclose(F);
	//輸出yuv檔案
	snprintf(temp, 1024, "%s.yuv", filename);
	F = fopen(temp, "wb");
	fwrite(components[0], width, height, F);
	fwrite(components[1], width * height / 4, 1, F);
	fwrite(components[2], width * height / 4, 1, F);
	fclose(F);
}

運行完成后在根目錄中得到:
在這里插入圖片描述
用YUVviewer觀看:
在這里插入圖片描述

2、程式除錯程序的理解

(1)理解程式設計的整體框架

在這里插入圖片描述

(2)理解三個結構體的設計目的

struct huffman_table

用來存盤Huffman碼表,

struct huffman_table
{
  /* Fast look up table, using HUFFMAN_HASH_NBITS bits we can have directly the symbol,
   * if the symbol is <0, then we need to look into the tree table */
  short int lookup[HUFFMAN_HASH_SIZE];
  /* code size: give the number of bits of a symbol is encoded */
  unsigned char code_size[HUFFMAN_HASH_SIZE];
  /* some place to store value that is not encoded in the lookup table 
   * FIXME: Calculate if 256 value is enough to store all values
   */
  uint16_t slowtable[16-HUFFMAN_HASH_NBITS][256];
};

struct component

儲存當前8×8塊中有關解碼的資訊,

struct component 
{
  unsigned int Hfactor; //水平采樣因子
  unsigned int Vfactor; //垂直采樣因子
  float *Q_table;		//8x8塊使用的量化表
  struct huffman_table *AC_table; //AC Huffman表
  struct huffman_table *DC_table; //DC Huffman表
  short int previous_DC;	//前一個塊的直流DCT系數
  short int DCT[64];		//DCT系數
#if SANITY_CHECK
  unsigned int cid;
#endif
};

struct jdec_private

JPEG資料流結構體,

struct jdec_private
{
  /* Public variables */
  uint8_t *components[COMPONENTS];
  unsigned int width, height;	/* Size of the image */
  unsigned int flags;

  /* Private variables */
  const unsigned char *stream_begin, *stream_end;
  unsigned int stream_length;

  const unsigned char *stream;	/* Pointer to the current stream */
  unsigned int reservoir, nbits_in_reservoir;

  struct component component_infos[COMPONENTS];
  float Q_tables[COMPONENTS][64];		/* quantization tables */
  struct huffman_table HTDC[HUFFMAN_TABLES];	/* DC huffman tables   */
  struct huffman_table HTAC[HUFFMAN_TABLES];	/* AC huffman tables   */
  int default_huffman_table_initialized;
  int restart_interval;
  int restarts_to_go;				/* MCUs left in this restart interval */
  int last_rst_marker_seen;			/* Rst marker is incremented each time */

  /* Temp space used after the IDCT to store each components */
  uint8_t Y[64*4], Cr[64], Cb[64];

  jmp_buf jump_state;
  /* Internal Pointer use for colorspace conversion, do not modify it !!! */
  uint8_t *plane[COMPONENTS];

};

(3)理解在視音頻編解碼除錯中TRACE的目的和含義

TRACE活動前處理器塊,用來協助程式的除錯,在本程式的頭檔案tinyjpeg.h中將TRACE設為1,表示程式正常除錯運行,若想關閉,可設為0,

#define TRACE 1//add by nxn

3、輸出量化矩陣和Huffman碼表

在頭檔案tinyjpeg.h中宣告要輸出的檔案:

FILE* qfile;//量化矩陣txt檔案
FILE* hfile;//Huffman碼表txt檔案

(1)量化矩陣

  1. 在創建量化矩陣的函式build_quantization_table()中添加量化矩陣輸出代碼;
	//輸出所有量化矩陣
	qfile = fopen("quan.txt", "a");
	for (i = 0; i < 8; i++) {
		for (j = 0; j < 8; j++) {
			fprintf(qfile, "%d\t", ref_table[*zz]);
			*qtable++ = ref_table[*zz++] * aanscalefactor[i] * aanscalefactor[j];
		}
		fprintf(qfile, "\n");
	}
  1. 在運用此函式的地方,即量化表決議函式parse_DQT()中添加代碼進行量化矩陣檔案的更新寫入,
#if TRACE
	fprintf(p_trace, "< DQT marker\n");
	fflush(p_trace);
	//更新列印量化矩陣
	fprintf(qfile, "DQT ID: %d\n", qi);
	fflush(qfile);
#endif

(2)Huffman碼表

  1. 在Huffman碼表創建的地方即函式build_huffman_table()內添加代碼列印輸出Huffman碼表,
if TRACE
		fprintf(p_trace, "val=%2.2x code=%8.8x codesize=%2.2d\n", val, code, code_size);
		fflush(p_trace);
		fprintf(hfile, "val=%2.2x code=%8.8x codesize=%2.2d\n", val, code, code_size);
		fflush(hfile);
#endif
  1. 在Huffman碼表決議的地方,即函式parse_DHT()中添加代碼實作輸出Huffman碼表的分類(DC或AC及序號),
//輸出huffman碼表
	hfile = fopen("huff.txt", "a");
	while (length > 0) {
		index = *stream++;

		/* We need to calculate the number of bytes 'vals' will takes */
		huff_bits[0] = 0;
		count = 0;
		for (i = 1; i < 17; i++) {
			huff_bits[i] = *stream++;
			count += huff_bits[i];
		}
#if SANITY_CHECK
		if (count >= HUFFMAN_BITS_SIZE)
			snprintf(error_string, sizeof(error_string), "No more than %d bytes is allowed to describe a huffman table", HUFFMAN_BITS_SIZE);
		if ((index & 0xf) >= HUFFMAN_TABLES)
			snprintf(error_string, sizeof(error_string), "No more than %d Huffman tables is supported (got %d)\n", HUFFMAN_TABLES, index & 0xf);
#if TRACE
		fprintf(p_trace, "Huffman table %s[%d] length=%d\n", (index & 0xf0) ? "AC" : "DC", index & 0xf, count);
		fflush(p_trace);
		fprintf(hfile, "Huffman table %s[%d] length=%d\n", (index & 0xf0) ? "AC" : "DC", index & 0xf, count);
		fflush(hfile);

(3)輸出結果

量化矩陣(0為DC,1為AC):
在這里插入圖片描述

Huffman碼表(展示部分):
在這里插入圖片描述

四、實驗結論

通過本次實驗:

  1. 掌握了JPEG編解碼系統的基本原理,
  2. 成功除錯了復雜的資料壓縮演算法實作的代碼,
  3. 最后根據代碼理解進行了一定的修改,實作了實驗要求的資料輸出,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/286502.html

標籤:其他

上一篇:實驗五-JPEG原理分析及JPEG解碼器的除錯

下一篇:C語言快速了解(和bug郭一起學C系列1)

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more