欧美成人午夜精品久久久,国产?V天堂一区二区三区,欧美精品va在线观看,亚洲一区二区三区免费在线观看,av无码精品一区二区久久,欧美性爱视频不卡一区三区,欧美乱人伦视频在线观看,国产一级牲交高潮

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運營的一線實戰(zhàn)洞察。

用C語言實現(xiàn)PNG/JPEG轉(zhuǎn)BMP:從解碼原理到工程實踐

用C語言實現(xiàn)PNG/JPEG轉(zhuǎn)BMP:從解碼原理到工程實踐 簡介這是一份面向C語言學(xué)習(xí)者和圖像處理開發(fā)者的圖片格式轉(zhuǎn)換工程圍繞PNG與JPEG轉(zhuǎn)BMP的核心任務(wù)同時涵蓋圖片縮放、旋轉(zhuǎn)等常見操作。工程基于VC6.0開發(fā)包含完整C語言源碼、libpng與jpeglib庫文件、頭文件及可執(zhí)行程序壓縮包共243個文件約14.15MB目錄按源碼、庫、示例圖片和工程配置分類既有16張測試用PNG/JPG原圖也有轉(zhuǎn)換后的BMP結(jié)果及配套音頻素材便于直接運行和對照驗證。目前已有2646人學(xué)習(xí)下載。通過學(xué)習(xí)這套源碼可以掌握PNG的IHDR/IDAT塊解析、JPEG的DCT與量化解碼流程、BMP文件頭及像素數(shù)據(jù)的寫入規(guī)則如4字節(jié)行對齊以及最近鄰插值、雙線性插值和仿射變換等圖像處理算法的C語言實現(xiàn)從解碼到編碼全流程均有代碼呈現(xiàn)。對于準(zhǔn)備課程設(shè)計、畢業(yè)設(shè)計或想深入理解圖像編碼原理、文件I/O與內(nèi)存操作的開發(fā)者這是一份可直接參考的完整實例。1. 用 C 語言實現(xiàn) PNG/JPEG 轉(zhuǎn) BMP為什么說是件反直覺的苦差事圖片格式轉(zhuǎn)換這件事表面上是“讀文件、改個頭、寫文件”實際做起來才發(fā)現(xiàn) BMP 這個“最笨”的格式反而是照妖鏡。PNG 有濾波、有 zlib 壓縮、有 Adam7 隔行JPEG 有 Huffman 表、有量化矩陣、有 4:2:0 色度抽樣而 BMP 只認(rèn)原始像素數(shù)組。把前面兩種格式解碼成原始 RGB 再交給 BMP等于把一個圖片格式轉(zhuǎn)換工具做成了“半個解碼器”。很多人在網(wǎng)上找現(xiàn)成的 C 語言轉(zhuǎn)換源碼包下載后一跑就花屏、偏色、錯行根本不是代碼寫錯而是對格式規(guī)范理解得不到位。這篇文章拿一份具體的轉(zhuǎn)換工程拆解來龍去脈從解碼管線到 BMP 落盤細(xì)節(jié)再到三類高頻踩坑記錄。適合嵌入式開發(fā)者、圖像算法入門者以及所有想在 C 語言層面徹底搞懂圖片格式的人。新手能照步驟跑通熟手可以跳過基礎(chǔ)部分直接看邊界和參數(shù)坑。2. 拆開這份轉(zhuǎn)換工程文件構(gòu)成與整體管線拿到一份號稱“C 語言實現(xiàn) PNG/JPEG 轉(zhuǎn) BMP”的資源第一件事不是打開 main.c而是把整個目錄結(jié)構(gòu)摸清。源碼包的質(zhì)量從文件組織方式就能看出一大半很多 GitHub 上隨手傳的工程只有一兩個 .c 文件里面塞了上千行裸代碼真要去改一個參數(shù)要翻半天。這份工程屬于能直接動手復(fù)現(xiàn)的類型各個模塊分得比較干凈下面逐個細(xì)說。2.1 目錄結(jié)構(gòu)哪些文件是核心哪些是輔助先看整體組織典型的劃分方式是把解碼器、編碼器、公共工具、入口邏輯分開。以下目錄結(jié)構(gòu)是工程里最常見、也最值得保留的一種組織方式converter/ ├── src/ │ ├── main.c # 入口解析命令行參數(shù)調(diào)度轉(zhuǎn)換流程 │ ├── png_decoder.c/h # PNG 解碼IDAT 解壓、濾波反解、顏色轉(zhuǎn)換 │ ├── jpeg_decoder.c/h # JPEG 解碼Huffman 解碼、反量化、逆 DCT │ ├── bmp_writer.c/h # BMP 編碼文件頭、信息頭、像素數(shù)據(jù)落盤 │ └── common.c/h # 公共工具文件讀寫、內(nèi)存分配、錯誤碼定義 ├── test/ │ ├── sample_png/ # 各種 color type 的 PNG 測試圖 │ ├── sample_jpeg/ # 各種抽樣方式的 JPEG 測試圖 │ └── verify.py # 像素級對比腳本 └── Makefile這里最關(guān)鍵的是 png_decoder 和 jpeg_decoder這兩個模塊決定了轉(zhuǎn)換質(zhì)量。main.c 里沒有放任何解碼邏輯只做參數(shù)解析和流程編排這種寫法值得借鑒。很多初學(xué)者寫的轉(zhuǎn)換工具把所有代碼堆在 main 函數(shù)里最后連自己都分不清哪一段是濾波反解、哪一段是顏色空間轉(zhuǎn)換。有幾個工程還帶了進(jìn)階擴展比如 bmp_writer 里不只有 24 位真彩輸出還留了 8 位調(diào)色板模式的開關(guān)這意味著能把 RGB888 量化成 256 色輸出。這個功能對「嵌入式 LCD 顯示」這個場景非常有用因為很多屏幕只有 8 位或 16 位色深后面我會單獨講調(diào)色板部分怎么驗證。2.2 從文件到像素轉(zhuǎn)換管線的三段式設(shè)計整個系統(tǒng)的核心管線分三段輸入解碼、像素處理、BMP 編碼。先看轉(zhuǎn)換流程圖這個圖在腦中的比寫在紙上的重要因為調(diào)試問題時要靠它定位階段PNG 文件 → PNG 解碼器 → RGB888 像素緩沖 → BMP 編碼器 → BMP 文件 JPEG 文件 → JPEG 解碼器 → RGB888 像素緩沖 → BMP 編碼器 → BMP 文件為什么要統(tǒng)一成 RGB888 中間格式這是處理圖片格式轉(zhuǎn)換的常見做法BMP 只是最終包裝PNG 和 JPEG 解碼出來的數(shù)據(jù)統(tǒng)一轉(zhuǎn)成 RGB888中間層的代碼復(fù)用率最高。如果需要擴展成輸出 PPM、TGA 等其他格式只需要再寫一個編碼器解碼部分完全不用動??创a時優(yōu)先看數(shù)據(jù)流的走向。先打開 png_decoder.c從頭文件里的結(jié)構(gòu)體定義開始看// 解碼輸出的統(tǒng)一像素緩沖結(jié)構(gòu) typedef struct { int width; // 圖像寬度像素為單位 int height; // 圖像高度像素為單位 int channels; // 通道數(shù)3 RGB4 RGBA unsigned char *data; // 像素數(shù)據(jù)按行存儲 } ImageBuffer; // PNG 關(guān)鍵信息結(jié)構(gòu)體 typedef struct { int bit_depth; // 位深8、16 等 int color_type; // 顏色類型0灰度2真彩3索引6真彩alpha int interlace_method; // 0非隔行1Adam7 隔行 int width; int height; } PNGInfo;參數(shù)說明channels 字段非常關(guān)鍵——PNG 的 color type 為 6RGBA時解碼出來有 4 個通道但 BMP 通常落地為 3 通道。這個通道數(shù)變換要在像素處理階段完成而不是在解碼器里改原因是 alpha 通道的取舍策略丟棄還是預(yù)乘應(yīng)該由轉(zhuǎn)換策略決定而不是解碼器自己決定。整個管線的順序是PNG 解碼器負(fù)責(zé)把壓縮的 IDAT 數(shù)據(jù)還原成帶有濾波信息的原始掃描線然后逐行做濾波反解最后根據(jù) color type 轉(zhuǎn)成 RGB888。JPEG 解碼器則是從熵解碼開始逐步過反量化、逆 DCT、顏色空間轉(zhuǎn)換。兩類解碼器輸出統(tǒng)一格式后BMP 編碼器只管落盤不需要知道數(shù)據(jù)是從 PNG 還是 JPEG 來的。3. PNG 轉(zhuǎn) BMP 的實現(xiàn)拆解從 IDAT 到像素數(shù)組PNG 轉(zhuǎn) BMP 的關(guān)鍵路徑是解析文件頭、解壓 IDAT、處理濾波、轉(zhuǎn)換顏色類型。這里面的難點不在文件頭而在“解壓后怎么處理”。PNG 的像素數(shù)據(jù)走 zlib 壓縮后并不是直接就是 RGB 數(shù)組每一行開頭還帶了一個濾波類型字節(jié)。這一章把整個鏈路走一遍重點落在濾波反解和顏色轉(zhuǎn)換上。3.1 PNG 解碼的關(guān)鍵步驟簽名驗證、IHDR 解析、IDAT 解壓PNG 文件開頭是固定的 8 字節(jié)簽名0x89 P N G \r \n 0x1a \n。代碼里驗證簽名的方式是int png_check_signature(const unsigned char *data, size_t size) { static const unsigned char sig[8] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }; if (size 8) return -1; return memcmp(data, sig, 8) 0 ? 0 : -1; }簽名驗證不通過就直接返回“不是 PNG 文件”的錯誤碼。這個看似基礎(chǔ)的檢查實際能過濾掉很多無效輸入我在調(diào)試時遇到過把 JPEG 改名成 .png 傳進(jìn)來的情況沒有簽名檢查的話后面解碼會直接內(nèi)存越界。簽名之后是 IHDR 塊。IHDR 是第一個關(guān)鍵塊固定 13 字節(jié)數(shù)據(jù)長度包含寬、高、位深、顏色類型、壓縮方法、濾波方法、隔行方法。解析方式和寫在紙上的格式規(guī)范完全對應(yīng)int parse_ihdr(const unsigned char *buf, PNGInfo *info) { info-width (buf[0] 24) | (buf[1] 16) | (buf[2] 8) | buf[3]; info-height (buf[4] 24) | (buf[5] 16) | (buf[6] 8) | buf[7]; info-bit_depth buf[8]; info-color_type buf[9]; // buf[10] 是壓縮方法PNG 規(guī)范里固定為 0 // buf[11] 是濾波方法PNG 規(guī)范里固定為 0 info-interlace_method buf[12]; return 0; }參數(shù)說明寬高都是大端序存儲所以不能直接當(dāng)小端讀。很多轉(zhuǎn)換代碼在這個地方直接取 buf[0] 作為低字節(jié)遇到寬高大于 255 的圖就翻車。位深和顏色類型要組合起來判斷合法性位深為 8 時支持所有顏色類型位深為 16 時只支持灰度、真彩、真彩alpha——遇到不合法的組合直接拒絕不要試圖去“猜”。解壓 IDAT 是 PNG 解碼的性能瓶頸。zlib 解壓后的數(shù)據(jù)是“原始掃描線 濾波類型字節(jié)”交錯的形式。解壓方式用 zlib 庫是最省事的但如果你要寫的是嵌入式環(huán)境下的轉(zhuǎn)換器用 miniz 是更常見的選擇——miniz 是單文件庫嵌入工程方便API 跟 zlib 兼容#include miniz.h int png_decompress_idat(const unsigned char *compressed, size_t comp_len, unsigned char **raw, size_t *raw_len) { // 用 miniz 的 tinfl_decompress_mem_to_heap 直接解到堆上 mz_ulong estimated comp_len * 4 1024; // 初始估算不夠會自動增長 *raw (unsigned char *)tinfl_decompress_mem_to_heap(compressed, comp_len, (mz_ulong *)raw_len, 0); if (!*raw) return -1; return 0; }邏輯說明這段代碼調(diào)tinfl_decompress_mem_to_heap一次性解出全部數(shù)據(jù)。估算大小不是精確值庫內(nèi)部會處理膨脹的情況但如果你的工程對內(nèi)存敏感可以改成用tinfl_decompress分塊解配合已知的原始大小分配合適緩沖。原始大小怎么算就是每行寬度×通道數(shù)×位深/8 1 個濾波字節(jié)乘以高度前提是知道 color type 對應(yīng)的通道數(shù)——這就是前面 PNGInfo 存在的意義。3.2 濾波反解的五種類型與逐行恢復(fù)算法IDAT 解壓后的數(shù)據(jù)不能直接當(dāng)像素用。每一行開頭多了一個濾波類型字節(jié)而每一行的像素值是經(jīng)過濾波處理的差分值必須逐行反向處理。這就是 PNG 和 BMP 之間最本質(zhì)的一層差異BMP 存的是絕對像素值PNG 存的是“經(jīng)過濾波后的值”。濾波類型共有五種0 無濾波、1 左側(cè)差分、2 上方差分、3 平均、4 Paeth 預(yù)測?;謴?fù)算法的核心邏輯是逐字節(jié)重建int png_unfilter_line(unsigned char *line, unsigned char *prev_line, int bytes_per_pixel, int line_bytes, int filter_type) { int i; for (i 0; i line_bytes; i) { unsigned char raw line[i]; unsigned char left (i bytes_per_pixel) ? line[i - bytes_per_pixel] : 0; unsigned char up (prev_line) ? prev_line[i] : 0; unsigned char up_left (prev_line i bytes_per_pixel) ? prev_line[i - bytes_per_pixel] : 0; switch (filter_type) { case 0: // 無濾波直接使用不需要修正 break; case 1: // Sub: 原始值 左側(cè)值 line[i] raw left; break; case 2: // Up: 原始值 上方值 line[i] raw up; break; case 3: // Average: 原始值 (左 上) / 2 line[i] raw ((left up) 1); // 注意是除以 2 后向下取整 break; case 4: { // Paeth: 原始值 左/上/左上三者間的預(yù)測值 int p left up - up_left; int pa abs(p - left); int pb abs(p - up); int pc abs(p - up_left); unsigned char predictor; if (pa pb pa pc) predictor left; else if (pb pc) predictor up; else predictor up_left; line[i] raw predictor; break; } } } return 0; }邏輯說明注意循環(huán)的順序必須從左到右逐字節(jié)處理。Sub 濾波里后面的字節(jié)依賴前面已經(jīng)恢復(fù)的字節(jié)如果先處理右邊就全錯了。Up 和 Average 依賴上一行的對應(yīng)位置所以必須按行從上到下處理絕不能并行。Paeth 的預(yù)測值選擇規(guī)則是取左邊、上方、左上三者中與“左上-左上”預(yù)測值最接近的那個。參數(shù)說明bytes_per_pixel不是固定值它取決于 color type——灰度 1 字節(jié)、真彩 3 字節(jié)、真彩alpha 4 字節(jié)。8 位索引色也是 1 字節(jié)。16 位深度時每個通道占 2 字節(jié)bytes_per_pixel 要翻倍。這個參數(shù)錯了濾波反解出來的圖像會出現(xiàn)“像素錯位 偏色”的混合癥狀這是最常見的翻車現(xiàn)場之一。濾波處理完后如果原圖是非隔行的此時數(shù)據(jù)已經(jīng)是完整的圖像像素。但很多測試圖用的是 Adam7 隔行編碼解出來的數(shù)據(jù)是 7 個不完整的子圖必須先合成再繼續(xù)。合成方式是按 Adam7 的 7 個 pass把每個 pass 的像素放到最終位置代碼里維護(hù)一個 8x8 的偏移表7 個 pass 覆蓋 64 個位置。不少轉(zhuǎn)換器直接不支持隔行 PNG報一個“不支持的隔行模式”錯誤就退出。從工程角度對不支持的功能直接報錯比輸出花屏要好得多。3.3 顏色類型轉(zhuǎn)換灰度、索引色、RGBA 統(tǒng)一成 RGB888PNG 的 color type 為 2真彩時濾波后的數(shù)據(jù)就是 RGB888直接拷貝到 ImageBuffer 即可。但灰度type 0、索引色type 3、真彩alphatype 6都要額外處理?;叶茸詈唵蚊總€像素的 RGB灰度值。索引色要查 PLTE 塊先解析調(diào)色板// 解析 PLTE 塊最多 256 項每項 3 字節(jié) (R,G,B) int parse_plte(const unsigned char *data, size_t len, unsigned char palette[][3]) { if (len % 3 ! 0) return -1; int count len / 3; if (count 256) count 256; for (int i 0; i count; i) { palette[i][0] data[i * 3]; palette[i][1] data[i * 3 1]; palette[i][2] data[i * 3 2]; } return count; } // 索引色轉(zhuǎn) RGB888 void indexed_to_rgb(const unsigned char *src, unsigned char *dst, int pixel_count, const unsigned char palette[][3]) { for (int i 0; i pixel_count; i) { unsigned char idx src[i]; dst[i * 3] palette[idx][0]; dst[i * 3 1] palette[idx][1]; dst[i * 3 2] palette[idx][2]; } }RGBA 轉(zhuǎn) RGB 的處理方式在轉(zhuǎn)換策略上有分歧。直接丟棄 alpha 是最簡單的做法但如果原圖帶有透明背景丟掉 alpha 后透明區(qū)域的 RGB 值可能是任意值常見是黑或白轉(zhuǎn)出來的 BMP 會有一個黑色或白色的底。處理時先看 PLTE 和 tRNS 塊有沒有指定透明色再看 alpha 通道的值至少要把 alpha0 的像素 RGB 值統(tǒng)一設(shè)置成白色后續(xù)如果要嵌到其他場景里再合成這樣做翻車概率小一些void rgba_to_rgb(const unsigned char *src, unsigned char *dst, int pixel_count) { for (int i 0; i pixel_count; i) { unsigned char r src[i * 4]; unsigned char g src[i * 4 1]; unsigned char b src[i * 4 2]; unsigned char a src[i * 4 3]; if (a 0) { // 全透明像素RGB 置為白色避免出現(xiàn)隨機黑點 dst[i * 3] dst[i * 3 1] dst[i * 3 2] 0xFF; } else { dst[i * 3] r; dst[i * 3 1] g; dst[i * 3 2] b; } } }邏輯說明嚴(yán)格來說如果 alpha 是 0 到 255 之間的半透明值正確的做法是把 RGB 跟背景色做 alpha 混合。但大多數(shù)圖片格式轉(zhuǎn)換工具對半透明的策略就是“丟掉 alpha 信息保留未預(yù)乘的 RGB”這一點要在代碼注釋里寫明。半透明區(qū)域的 RGB 值在 PNG 里的定義是“未預(yù)乘的顏色”丟掉 alpha 后顏色會偏亮或偏暗這是 PNG 轉(zhuǎn) BMP 的一個固有信息損失不是 bug。4. JPEG 轉(zhuǎn) BMP 的實現(xiàn)拆解Huffman 解碼與 DCT 的完整鏈路JPEG 轉(zhuǎn) BMP 比 PNG 要復(fù)雜一個量級。PNG 的復(fù)雜度在線性濾波JPEG 的復(fù)雜度在熵解碼之后的非線性環(huán)節(jié)Huffman 解碼、差分 DC、Zigzag 掃描、反量化、逆 DCT、YCbCr 轉(zhuǎn) RGB、色度上采樣。任何一個環(huán)節(jié)錯了輸出圖不是整體偏色就是出現(xiàn) 8x8 的塊狀噪聲。這一章不搞簡化版按完整解碼鏈路走你可以對照自己手里的工程逐段檢查。4.1 從文件頭到量化表SOI、DQT、DHT 的解析順序JPEG 文件由段Segment組成。解析的基本模式是掃描標(biāo)記Marker根據(jù)標(biāo)記類型分發(fā)到不同的處理函數(shù)。以下是常見標(biāo)記的說明標(biāo)記名稱說明0xD8SOI文件起始固定出現(xiàn)在開頭0xE0~0xEFAPPn應(yīng)用數(shù)據(jù)段常見為 JFIF 信息0xDBDQT定義量化表至少要有一個0xC0SOF0幀起始包含寬高等關(guān)鍵信息0xC4DHT定義 Huffman 表0xDASOS掃描起始圖像數(shù)據(jù)從這里開始0xD9EOI文件結(jié)束JPEG 規(guī)定量化表和 Huffman 表必須先于 SOS 出現(xiàn)但 DHT 可以拆成多段分別定義。寫解析器時要注意不能假設(shè)所有表在一個段里就給齊了。解碼器的狀態(tài)機按“讀標(biāo)記→讀段長→分發(fā)”循環(huán)這是整個 JPEG 解碼器的基礎(chǔ)骨架。量化表的解析要注意的一個細(xì)節(jié)是表 ID 和精度打包在一個字節(jié)里。高 4 位是精度08 位116 位低 4 位是表 ID。解碼時要分別取出來int parse_dqt(const unsigned char *buf, int len, QuantTable tables[4]) { int offset 0; while (offset len) { int pq buf[offset] 4; // 精度08bit116bit int tq buf[offset] 0x0F; // 表 ID0~3 offset; if (pq 0) { for (int i 0; i 64; i) { tables[tq].values[i] buf[offset i]; } offset 64; } else { // 16 位量化表每個值占 2 字節(jié)大端序 for (int i 0; i 64; i) { tables[tq].values[i] (buf[offset i * 2] 8) | buf[offset i * 2 1]; } offset 128; } } return 0; }參數(shù)說明JPEG 量化表是自然序而非 Zigzag 序在反量化之前要先把系數(shù)恢復(fù)到 8x8 的自然位置。這個問題我在初寫時踩過不熟悉編碼規(guī)范的話容易直接把量化表當(dāng) Zigzag 序用行頻和列頻就顛倒了。解決方式是在反量化前重排 Zigzag 序。4.2 熵解碼與逆 DCTDC 差分累積、Zigzag 重排、IDCT 公式JPEG 的核心是離散余弦變換DCT。編碼時把圖像分成 8x8 塊每個塊做 DCT 變換得到 64 個頻域系數(shù)再對系數(shù)量化和熵編碼。解碼時流程倒過來先熵解碼得到 64 個系數(shù)然后反量化再做逆 DCT 得到像素塊。這里的系數(shù)排列是 Zigzag 序做 IDCT 前要重排static const unsigned char zigzag[64] { 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 }; // 反量化 Zigzag 重排 void dequantize_block(const int *coeff_zz, const QuantTable *qtable, int coeff_natural[64]) { for (int i 0; i 64; i) { int natural_idx zigzag[i]; coeff_natural[zigzag[i]] coeff_zz[i] * qtable-values[zigzag[i]]; } }邏輯說明coeff_zz是從熵解碼器出來的系數(shù)按 Zigzag 序號排列重排到自然序后行號 idx / 8列號 idx % 8這個順序才能喂給逆 DCT 函數(shù)。DC 系數(shù)是差分編碼的——當(dāng)前塊的 DC 值要加上上一個塊的值才是真正的 DC。這是 JPEG 解碼器和 PNG 濾波反解中“逐行必須串行”相似的約束但是按塊串行int prev_dc[4] {0, 0, 0, 0}; // 最多 4 個分量 // 每處理完一個塊后 prev_dc[component] diff_dc;這個 prev_dc 數(shù)組要按分量分開維護(hù)不能用一個全局變量。Y、Cb、Cr 各自的 DC 預(yù)測器是獨立的混在一起會出現(xiàn)深色圖像上出現(xiàn)橫向漸變的條紋。逆 DCT 的整數(shù)實現(xiàn)有很多種浮點版本最簡單也最不容易出錯。如果性能有要求可以用 AAN 整數(shù)近似算法但精度不如浮點void idct_8x8(const int block[64], unsigned char out[64]) { double tmp[64]; for (int u 0; u 8; u) { for (int v 0; v 8; v) { double sum 0.0; for (int x 0; x 8; x) { for (int y 0; y 8; y) { double cu (x 0) ? 0.7071067811865476 : 1.0; double cv (y 0) ? 0.7071067811865476 : 1.0; sum block[x * 8 y] * cu * cv * cos((2 * x 1) * u * M_PI / 16.0) * cos((2 * y 1) * v * M_PI / 16.0); } } tmp[u * 8 v] 0.25 * sum; } } for (int i 0; i 64; i) { int val (int)(tmp[i] 128.5); out[i] (unsigned char)(val 0 ? 0 : (val 255 ? 255 : val)); } }邏輯說明這個雙重循環(huán)沒有做任何優(yōu)化但正確性有保證。輸出要加 128 的偏移量因為 DCT 變換假設(shè)輸入范圍是 [-128, 127]輸出要轉(zhuǎn)回 [0, 255]。0.5是做四舍五入而不是截斷不加的話會出現(xiàn)整體偏暗的一致性問題。4.3 色度抽樣與顏色空間4:2:0 上采樣和 YCbCr 轉(zhuǎn) RGBJPEG 最坑的地方是色度抽樣。大多數(shù) JPEG 圖像用 4:2:0 抽樣——亮度 Y 每個像素都有色度 Cb、Cr 每 2x2 像素塊共享一個值。解碼時必須先把 Cb、Cr 向上采樣到和 Y 同尺寸再做顏色轉(zhuǎn)換。void upsample_chroma(const unsigned char *cb_small, const unsigned char *cr_small, unsigned char *cb_big, unsigned char *cr_big, int width_big, int height_big, int h_scale, int v_scale) { for (int y 0; y height_big; y) { int sy y / v_scale; for (int x 0; x width_big; x) { int sx x / h_scale; cb_big[y * width_big x] cb_small[sy * (width_big / h_scale) sx]; cr_big[y * width_big x] cr_small[sy * (width_big / h_scale) sx]; } } }邏輯說明最簡單的最近鄰上采樣。效果可以接受但有些工程會做雙線性插值抗鋸齒效果更好。上采樣維度計算要嚴(yán)格按 h_scale 和 v_scale 來4:2:0 時 h_scale2v_scale2色度平面寬高各減半4:2:2 時 h_scale2v_scale1 只有寬度減半。如果從 SOF0 里拿到的是“1x1、2x1、1x2、2x2”這類抽樣因子而非直接寬高要做映射判斷// SOF0 里每個分量的抽樣因子 unsigned char h_sampling sof_data[comp_index * 3 1] 4; unsigned char v_sampling sof_data[comp_index * 3 1] 0x0F; // 寬高由 Y 分量決定色度分量的實際尺寸按采樣因子換算YCbCr 轉(zhuǎn) RGB 的公式在工程里寫死了但注意 JPEG 的 YCbCr 是 ITU-R BT.601 范圍不同于 JPEG 編碼時的全范圍。轉(zhuǎn)換公式// 輸入: Y 范圍 [0,255], Cb/Cr 范圍 [0,255] (未做 128 偏移) // 輸出: RGB 范圍 [0,255]需要做裁減以防止越界 int r (int)(Y 1.402 * (Cr - 128)); int g (int)(Y - 0.344136 * (Cb - 128) - 0.714136 * (Cr - 128)); int b (int)(Y 1.772 * (Cb - 128));邏輯說明Cb 和 Cr 在熵解碼后是帶符號的數(shù)值范圍轉(zhuǎn)為無符號時要加上 128 的偏移。如果不做偏移顏色會變成一種“負(fù)片色調(diào)”這是 JPEG 轉(zhuǎn) BMP 最容易肉眼發(fā)現(xiàn)的問題之一。轉(zhuǎn)換后的 RGB 要做 0~255 限幅因為逆 DCT 的浮點誤差和色度上采樣的插值會算出越界值。碰到底部有 SOS 段卻拿不到 DHT 表的情況說明源 JPEG 用了“一次性 Huffman 表”的特殊編碼方式把表放在 SOS 之后。這種情況現(xiàn)實中很少見但部分相機直出的 JPEG 會這么干。真遇到了解碼器不能原地崩潰要返回一個“不支持的 JPEG 變體”錯誤并注明原因——這里用 Haffman 表延遲解析的工程極少普通轉(zhuǎn)換場景直接拒絕問題不大。5. 轉(zhuǎn)換避坑指南最值得記下的五條實測踩坑記錄這一章是實際調(diào)試中反復(fù)遇到的經(jīng)典問題從“花屏”到“錯位”到“偏色”每條都帶具體原因和解決方法。如果你拿到的轉(zhuǎn)換工程有問題按這個清單逐個排查。5.1 BMP 文件打不開文件頭長度和像素偏移算錯現(xiàn)象生成的 BMP 能被圖片查看器識別但提示“文件損壞”或“不支持該格式”。用十六進(jìn)制工具看文件頭部發(fā)現(xiàn) bfOffBits 和實際像素數(shù)據(jù)起始位置對不上。原因BMP 文件頭寫入了標(biāo)準(zhǔn) 14 字節(jié) BITMAPFILEHEADER 加 40 字節(jié) BITMAPINFOHEADER但沒有考慮調(diào)色板的存在。如果輸出為 8 位索引色像素數(shù)據(jù)前面還有 1024 字節(jié)的調(diào)色板數(shù)據(jù)bfOffBits 應(yīng)該是 14 40 1024 1078而不是默認(rèn)的 54。解決寫 BMP 頭之前先確認(rèn)輸出位深和是否帶調(diào)色板bfOffBits 按實際數(shù)據(jù)布局計算。注意 biSizeImage 字段也要同步修正否則某些嚴(yán)格校驗的查看器如部分嵌入式的解碼庫會提前截斷。文件大小 bfSize bfOffBits biSizeImage這三處數(shù)值必須自洽。5.2 圖像行錯位行字節(jié)數(shù)沒有按 4 字節(jié)對齊現(xiàn)象轉(zhuǎn)換出來的 BMP 整體向左傾斜每一行圖相對于上一行偏移了幾個像素而且偏移量隨行號遞增。用查看器打開時能隱約認(rèn)出畫面內(nèi)容但整幅圖呈“階梯形”。原因BMP 規(guī)定每行的字節(jié)數(shù)必須是 4 的倍數(shù)。假設(shè)寬度為 101 像素、24 位真彩101 × 3 303 字節(jié)303 不是 4 的倍數(shù)需要補齊到 304 字節(jié)補 1 個 0x00。如果你的代碼直接按“兩字節(jié)對齊甚至不對齊”寫入BMP 讀取器每一行都會從錯誤的位置讀下一行階梯形就是這樣產(chǎn)生的。解決在寫入每一行像素后計算需要補齊的字節(jié)數(shù)用 0x00 填充。經(jīng)驗公式rowSize ((width × bytesPerPixel 3) / 4) × 4行間隔 rowSize - width × bytesPerPixel。驗證時輸出一組已知像素值如第一行全部像素設(shè)為紅色看偏移是否消除。5.3 JPEG 圖像整體發(fā)綠YCbCr 偏移量沒加現(xiàn)象圖像內(nèi)容能看清輪廓但整體色調(diào)嚴(yán)重偏綠膚色變成了奇怪的顏色暗部有一層綠色底色。原因YCbCr 轉(zhuǎn) RGB 時漏了把 Cb、Cr 減去 128。JPEG 中 Cb、Cr 是“零中心”的128 對應(yīng)零偏置不減去 128 相當(dāng)于色度信號整體偏移轉(zhuǎn)換后 G 通道被抬高因為 G 的公式里 Cb、Cr 是減項引發(fā)偏綠。紅色的物體往往會變暗藍(lán)色的物體變黑整個色調(diào)都亂了。解決轉(zhuǎn) RGB 前確認(rèn) Cb、Cr 都減了 128。如果庫函數(shù)里已經(jīng)有這個處理檢查是不是重復(fù)減了兩次——有些工程從熵解碼器拿到的 Cb、Cr 已經(jīng)做了偏移處理再減一次會變成反向偏移同樣產(chǎn)生偏色問題。驗證方式找一張色卡圖或標(biāo)準(zhǔn)測試圖轉(zhuǎn)換后取幾個已知色塊的 RGB 值跟原圖對比。5.4 PNG 隔行掃描圖轉(zhuǎn)換出來后只有部分區(qū)域有內(nèi)容現(xiàn)象轉(zhuǎn)換結(jié)果是 8x8 的“方格拼圖”看起來像采樣率降低部分區(qū)域有內(nèi)容部分區(qū)域是空白。改換另一個非隔行的 PNG 測試圖時一切正常。原因解碼器只處理了 7 個 pass 中的部分?jǐn)?shù)據(jù)。Adam7 隔行把圖像拆成 7 個 pass每個 pass 是原圖在特定行列位置的子采樣。如果代碼把 7 個 pass 的數(shù)據(jù)當(dāng)作 7 張獨立圖像拼接或重疊寫入結(jié)果就變成拼圖效果。解決正確實現(xiàn) Adam7 合成。每個 pass 都有各自的行列起始位置和步長需要按 pass 序號查表確定寫入目標(biāo)位置。如果不支持隔行掃描正確做法是掃描 IHDR 的 interlace 字段當(dāng)值為 1 時直接返回“暫不支持 Adam7 隔行”而不是輸出錯誤結(jié)果。大多數(shù)工具類轉(zhuǎn)換器不支持隔行是可以接受的但要明確告知用戶。5.5 JPEG 解碼出現(xiàn) 8x8 的塊狀噪聲現(xiàn)象圖像整體能識別但所有 8x8 像素塊之間有明顯亮度差異看起來像“馬賽克”特別是平坦區(qū)域如天空、純色背景邊界非常明顯。原因逆 DCT 的精度不夠或者反量化之后忘了做 IDCT、直接拿頻域系數(shù)當(dāng)像素值。還有種可能是 Zigzag 重排錯誤導(dǎo)致 DCT 系數(shù)位置顛倒。低頻系數(shù)放錯位置會影響整體亮度高頻系數(shù)放錯位置會出現(xiàn)顆粒狀紋理。解決逐段檢查解碼管線。最有效的定位方式是把 IDCT 后的數(shù)據(jù)暫時輸出成文件肉眼觀察塊效應(yīng)是否存在如果 IDCT 后正常、BMP 寫入后出現(xiàn)塊效應(yīng)問題在 BMP 寫入環(huán)節(jié)的字節(jié)序如果 IDCT 后就有塊效應(yīng)檢查 Zigzag 重排表和量化表的使用順序。6. 進(jìn)階驗證方法像素級對比腳本與調(diào)色板位深擴展這一章講兩個價值點怎么驗證轉(zhuǎn)換結(jié)果是否真正正確以及怎么把轉(zhuǎn)換器擴展到 8 位調(diào)色板 BMP。前幾章解決了“能轉(zhuǎn)”的問題這一章解決“轉(zhuǎn)得對”和“轉(zhuǎn)得更實用”的問題。6.1 像素級自動對比PSNR 和 MAE 校驗?zāi)_本人眼盯著圖看容易漏掉細(xì)節(jié)差異特別是 JPEG 轉(zhuǎn) BMP 這種有損轉(zhuǎn)換如果解碼器有輕微精度損失人眼很難分辨但像素級對比能立刻暴露問題。Python 腳本適合做這件事——C 的轉(zhuǎn)換器產(chǎn)生 BMPPython 用 Pillow 庫打開原圖和轉(zhuǎn)換結(jié)果逐像素對比并計算 PSNR峰值信噪比from PIL import Image import math def compare_images(src_path, dst_path): src Image.open(src_path).convert(RGB) dst Image.open(dst_path).convert(RGB) if src.size ! dst.size: print(f尺寸不一致: {src.size} vs {dst.size}) return src_pixels list(src.getdata()) dst_pixels list(dst.getdata()) mse 0 max_diff 0 for p1, p2 in zip(src_pixels, dst_pixels): d sum((a - b) ** 2 for a, b in zip(p1, p2)) mse d max_diff max(max_diff, max(abs(a - b) for a, b in zip(p1, p2))) mse / (len(src_pixels) * 3) psnr 10 * math.log10((255 ** 2) / mse) if mse 0 else float(inf) print(fMSE: {mse:.4f}, PSNR: {psnr:.2f} dB, 單像素最大差: {max_diff})參數(shù)說明PSNR 值大于 40dB 表示差異非常小30~40dB 基本可接受但可能有輕微色差低于 30dB 意味著解碼器有實質(zhì)性錯誤。max_diff能捕捉極端情況——比如某個像素差 100 以上說明在某個顏色通道上處理邏輯有問題。這個腳本的價值在調(diào) JPEG 解碼器時特別明顯。JPEG 是有損格式不能要求轉(zhuǎn)換結(jié)果和原圖像素級一致但 PSNR 穩(wěn)定在 40dB 以上用高質(zhì)量原圖測試說明解碼器的精度損失只是量化和浮點運算帶來的沒有結(jié)構(gòu)性錯誤。如果 PSNR 在 25dB 以下基本可以斷定解碼鏈路里有 bug按前面的避坑清單逐項排查。6.2 調(diào)色板模式與位深擴展從 24 位真彩到 8 位索引色真彩 BMP 文件體積大嵌入式場景常需要 8 位索引色 BMP。從 RGB888 量化到 256 色的方式直接用中位切分算法Median Cut或八叉樹量化。中位切分更適合從零實現(xiàn)// 中位切分量化把 RGB 空間遞歸劃分成 256 個桶 typedef struct { int r_min, r_max, g_min, g_max, b_min, b_max; int pixel_count; unsigned char r_avg, g_avg, b_avg; } ColorBox; int build_palette(unsigned char *pixels, int pixel_count, unsigned char palette[256][3]) { ColorBox boxes[256]; // 初始化一個覆蓋全部像素的 box按 RGB 范圍做遞歸切分 // 每次選像素數(shù)最多、顏色范圍最大的 box沿最長的通道切 // 最終每個 box 的平均 RGB 作為調(diào)色板項 return 0; // 返回實際使用的顏色數(shù) }邏輯說明中位切分的本質(zhì)是每次選一個 box找到“像素數(shù)最多”或“顏色范圍最大”的那個沿范圍最長的顏色通道切成兩個 box直到湊滿 256 個。處理上要注意一個細(xì)節(jié)統(tǒng)計像素顏色時用桶化將 8 位通道降到 5 位左右能顯著加快速度代價是輕微的色彩精度損失。調(diào)色板構(gòu)建后每個像素取“距離最近”的調(diào)色板項距離可以按歐氏距離或帶權(quán)重的距離計算——人眼對綠色更敏感可以給 G 通道高權(quán)重。寫 8 位 BMP 時文件布局變?yōu)?4 字節(jié)文件頭 40 字節(jié)信息頭 1024 字節(jié)調(diào)色板 像素索引數(shù)組。biBitCount 設(shè)為 8biClrUsed 設(shè)為 256。像素數(shù)據(jù)不是 RGB 三元組而是每個字節(jié)一個調(diào)色板索引。如果轉(zhuǎn)換器不支持調(diào)色板量化正確做法是明確返回“僅支持 24 位真彩輸出”而不是自動降級成灰度或截斷數(shù)據(jù)。這也是工程邊界管理的一部分——明確不做什么比硬做但做錯要好得多。從那以后我每次寫格式轉(zhuǎn)換工具都會強制在工程里放一個 test 目錄和一個像素級校驗?zāi)_本。原圖、中間結(jié)果、最終輸出三者的像素數(shù)據(jù)隨時可對比比對通過才算功能完成。否則在 JPEG 解碼器里改一個 Zigzag 表改完到底對不對不跑像素級對比是很難判斷的。這份工程的代碼組織方式和解碼細(xì)節(jié)可以作為你手頭轉(zhuǎn)換需求的起點——但它不是銀彈遇到特殊變體的圖片色彩配置 ICC、16 位 PNG、漸進(jìn)式 JPEG還是要回來補解碼器邊界。希望幫到你。本文還有配套的精品資源點擊獲取
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
久热69| 森林影视大全,最好看的2019年视频 | 亚洲激情综| 日本一级黄色电影| 久久999久久999久久999久久| 久久五月天合网| 五月天丁香欧美激情| 无码一区二区三区四区五区| 五月婷婷丁香啪啪| 成人在线观看一区| 另类图片五月激情| 色九九综合色| 日产精品一线二线三线芒果| 五月天综合在线| 色五月天在线观看| 17.c黄色| 亚洲第一色区| 五月婷婷六月基地| 久久婷婷五月天激情唯美| 99色这里| 亚洲日韩国产黑丝黑丝AVAV一区二区三区| 超碰人人射| 丁香花五月天婷婷成人社区| 综合AV网| 欧美综合激情| 色色综合网www| 99色色网| 久九男女天堂| 99ER热精品视频| 六月丁香啪啪| 天天射影院| 欧美在线操| 99热无码首页| 色婷婷操逼| 欧美高潮9| 色婷婷呢狠禁久禁| 超碰cap| 五月天激情四射| 超碰激情网| 五月丁香婷婷免费视频| 日韩综合久| 婷婷色五月天在线| 超碰97免费在线| 五月丁查人人| 五月久久婷婷天堂视频| 丁香五月婷婷亚洲综合精品| 99热最新网址| 五月丁香婷婷伊人| 9久久精品| 九九九九国产| 国产精品美女久久久久AV超清| AV中文在线| 欧美日韩成人在线| 图片区 小说区 区 亚洲五月| 六月婷婷开心| 4399无码视频二区| 婷婷色啪| AV美美午夜| 97色五月天| 99久久黄色顶级视频| 激情五月综合视频| 伊人啪啪网| 五月丁香六月激情啪| 五月婷婷六月奇米网丁香| 日日干夜夜撸夜夜骑| 狠狠婷婷爱| 九九99视频精品| 色婷婷丁香六月| 伍月激情天| 五月丁香六月婷婷玖玖| 婷婷六月天| 丁香六月激情四射| 日韩av一区二区在线/日产精品久久久 | 婷婷狠狠操| 久久激情五月| 逼里香不卡| 99re思思热久久| 婷婷婷婷婷婷婷婷| 狠狠综合网| 亚洲日韩乱码一区二区三区四区 | 欧美综合五月丁香六月婷| 久久婷婷伊人| dingxiangtingtingliuyue| 久久久精品色| 久久久婷婷| 天天干人人奸97| 色原狠狠综合| 99热欧| 国产成人av在线| 激情六月天婷婷| 9999久久久久| 婷丁香五月天| 欧美色色色色色色色| 97干视频在线| 激情五月四色| 精品婷婷五| 婷婷狠狠五月综合| 激情综合网五月婷婷| 99热热热99精品婷婷| 天天插综合| 91精品久久久久| 欧美成人精品A片免费一区99| 懂色av粉嫩AV蜜臀AV| 亚洲无码11| 亚洲天天免费| 热五月婷婷| 天天日天天插| 高清不卡一区| 这里只有精品免费视频| 国产精品18久久久| 日本狠狠爽| 六月丁香射婷婷欧美色图片| 99re思思热久久| 九色成人AV在线| 亚洲综合1024| 97影院一级片| 丁香五月在线播放| 99色| 久久中文人妻系列| 中文字幕在线不卡| 99热热热国产超碰| 97婷婷五月天| 香蕉影院色| 97干97色| pom538精品视频| 牛牛热这里只有jingpin| 久久久99日本大片| 激情五月天婷婷丁香| 桃色五月天| 久久激情婷婷| 五月天狠狠草| 狼人伊人天堂| 六月丁香激情综合| 好吊丝aV| 五月天婷婷色| 综合久久丁香婷婷,五月婷婷六月丁香,开心激情综合网,六月丁香在线观看,婷婷丁 | www.com久久久久久久久久久久久久久久久| 久久久久激情| 丁香五月天.com| 伊人婷婷99热精品| 怡红院精品视频久久久久久久久| 99精品成人无码A片观看金桔| 97碰碰在线观看视频| 久99久热只有精品国产99| 99综合视频一体| 男人的天堂av俄罗斯热| 亚洲五月天综合| 五月天成人小说| 婷婷五月天视频小说| 五月天婷婷综合免费| 影音先锋男人女人| 激情九九综合网| 色色综合网站| 玖玖在线资源视频| 成人精品视频99在线观看免费| 丁香五月天堂网| 99热这里只有精品免费| 欧美日韩成人在线网站| 五月天丁香成人社| 日韩欧洲亚洲| 婷婷五月激情小说| 精品网站99| www久久久| 日本色天堂| 五月丁香影院 | 婷婷综合成人五月天| 成人在线视频网| WWW99热| 天天天天天天操| 一区操| 激情五月婷婷综合色播小说| 伊人网色婷婷五月天| 97色色色色色色色色色色色色色| 怎么样可以看免费的一级av| 亚洲亚洲永久无码777777| 丁香婷婷色| 五月开心播播网| 五月天播播综合| 日本狠狠干| 熟女激情网| 亚洲无码99| 五月丁香六月婷婷综合免| 亚洲色婷婷| WWW.激情| 性生活视频98791| 99操网站| 久热久| 久久这里只有精品无码| 亚洲成人av在线| 婷婷九月丁香| 看久久性爱99视频| 天天成人综合| 婷婷六月久久| 99天堂在线观看免费视频| 国产精品五月天婷婷| 亚洲视频久久| 涩五月婷婷| 色色综合日韩| 人人操大| 久久久久9| 五月深爱婷婷| 99热性色| 亚洲字幕AV一区二区三区四区| 激情五月天免费视频| 婷色综合| 国产亚洲99久久精品| 五月天天天综合| 国产精品天天狠天天看| 七七色色综合| 色五月激情综合| 精品婷婷丁香五| 99人妻碰碰碰久久久久视| www.色婷婷| 成人片黄网站色大片免费毛片| 色天天综合| 啪啪丁香五月| 久久九网| 五月激情婷婷在线| 色五月天成人| 色综合天天网| 一区二区三区四区牛| 人妻中文字幕网| 五月天婷婷丁香导航| 99亚洲天堂| 丁香综合日产精品久久| 婷婷五月天开心网| 五月丁香婷婷基地| 精品九九视频| 久久激情视频99| 九月丁香八月婷婷加勒比| 六月激情网| 开心久久五月天| 五月婷婷激情在线| 国精产品一区一区三区免费视频| 色色丁香五月天| 天天干夜夜b| 久久天堂| 丁香五月久久社区| 五月Huangsewang| 人人九色| 精品五月天| 亚洲五月天第一综合干| 婷婷五月色综合| 国产伦亲子伦亲子视频观看| 成人丁香| 婷婷激情五月| 婷婷激情人妻| 99热这里只有精品2| 综合五月草| 色狠狠综合入口| 欧美成人精品A片免费一区99| 六月丁丁香| 综合久久丁香婷婷,五月婷婷六月丁香,开心激情综合网,六月丁香在线观看,婷婷丁 | 国产肥白大熟妇BBBB视频| 夜夜谢天天干| 极品人妻VIDEOSSS人妻| 日碰日| 男男野外做爰全过程69| 婷婷丁香五月社区亚洲| 综合网网欲色| 日韩精品999| 日本123区日韩欧美不卡在线看| 婷婷色色色| 六月婷婷色色网| 成人在线观看精品| 一区二区三区XXXXXX| 超级碰人人操人人干| 成人AV网站在线| 99热综合网| 精品久久9| 五月天婷婷久久视频| 五月天婷婷色小说| 九九久久五月天综合伊人| www.日本久久videos| 亚欧州精品视频| 色yeye欧美| 99色久| 久久五月天视频| 久久精品性爱视频,| 五月天激情小说婷婷| 79精品在线视频| 伊人六月无码视频| 夜色综合网| 婷婷五月色| 天天射影院| 99只有这里是精品| 丁香六月激情| 五月婷丁香| www.99热国产| 九色91国产| 婷婷五月天成人动漫| 夜夜做夜夜愛| 91碰碰| 欧美私人家庭影院| 91精品人妻少妇无码影院| 亚洲成人网在线观看| 国产日批视频免费播放| 思思热在线精品视频| 99操碰| 99热在线观看| 99热在线精品播放| 亚洲激情综合免费| av在线资源| 激情婷婷五月社区| 久久激情综合| 丁香五月婷婷基地| 亚洲天堂九九九| 婷婷99狠狠躁天天| 五月天精品| 极品人妻VIDEOSSS人妻| 性欧美日本| 99久久成人| 在线观看免费狠狠色丁香香综合| 婷婷丁香红五月91C| 久久狠狠干| 五月婷婷香蕉| 狠狠干夜夜干| 超碰不卡在线| 婷婷六月五月| 9热成人在线视频| 大香蕉婷婷| 久久性爱视频久久性爱视频| 日日爽夜夜爽| 日韩成人精品中文字幕| 久热黄色| 人人操操| 色婷婷久久综合中文久久一本| 色香蕉影院| 百度4399有码精品V在线观看| 色色婷婷五月天| 96色婷婷| 色久五月天| 久久性视频| 啪啪黄页网| 综合网五月天123| 99久视频| 99re热精品视频国| 色99在线视频| 伊人网欧美在线男人天堂五月丁香 | 亚洲中文无码成人| 久久xxxx| 人人澡天天色天天做| 99啪99| 99精品综合| 五月激情网五月综合网| 色婷婷五月天| 伊人国产婷婷五月天| 天天干天天干天天操| 91人操| 99无码视频| 久久激情婷婷| 丁香五月av| 91人人人人人人人| 激情五月五月婷婷| 亚洲精品视频电影| 91在线日| 九九热亚洲中文在线观看免费| 激情四射婷婷| 五月丁香啪啪| 色综合天天| 亚洲激情 久久| 激情丰满熟妇五月| 七月丁香五月婷婷在线| 亚洲激情免费视频观看| 激情五月婷婷视频一区二区三区| 玖玖午夜视频| 色狠狠综合| 婷婷五月亚洲综合| 激情小说婷婷小说| av免费在线看不卡无毒| 橾逼网| 另类丁香综合| 深夜男女福利刺激影院一区完整| 婷婷激情伍月网| 99色亚洲| 色情免费视频播放| 色五月婷婷激情基地| 婷婷五月天天爽| 色色色婷| 激情小说五月天| 色狠狠综合网| 91久久色| 99啪啪| 白天AV月月| 久久XX日本综合| 欧州色色| 精品视频这里只有精品| 亚洲成人日韩无码精品| 91一起艹| 亚洲精品久久久久久久久久吃药| 丁香五月777| 欧美婷婷| 婷婷开心久久| 激情五月综合网| 国产SUV精品一区二区883| 色约约视频一区二区三区四区五区| 婷婷十月激情综合网| 亚洲超级碰| AV九九| 狠狠干五码| 69综合在线| 91欧美| 另类小说五月天综合| 欧美日本不卡黄色片| 九月激情综合| 操你av| 婷婷激情视频| 91女人18毛片水多国产| 99热自拍| 色哟哟www| 色。 日日日| 91|九色|动漫| 婷婷视频在线碰| 激情六月丁香| 五月婷婷综合久久| 狠狠狠狠狠狠草| 色综合色色色色| 大香蕉伊人久久| 五月天天久久香| 伊人青草成人| 亚洲无码播放| 丁香五月综合久久| 操操综合网婷婷| 日日夜夜天天综合| 综合五月丁香六月婷婷| 婷婷精品综合| 五月丁香欧美综合免费视频| 成人五月天婷婷| 1区2区视频| 狠狠久久婷五月综合色| 色情综合网| 色色影院黄大片| 少妇搡BBBB搡BBB搡毛茸茸| 91丨九色丨熟女|新版| www.狠狠干com| 五月天五月色婷婷综合| 日韩综合天堂| 99热综合网| 91操在线| 亚洲视频另类| 伊人喵咪a V| 亚洲爆乳无码精品AAA片蜜桃| 日本啪啪网| 日本成人噜噜噜| 亚洲VA在线| 国产伊人五月天| 综合AV在线| 伊人狠狠色婷婷综合丁香一区| 95精品区一区二| 天天综合精品| 丰满少妇乱A片无码| 思思久久99| 97碰超级人人看| 播五月,色五月,开心五月播放器| 夜夜爽天天干| 五月丁香综合影院| 欧美久久网| 激情网婷婷五月天| 五月天婷婷AV| 噜噜噜噜婷婷五月天| 97碰久久| 亚洲激情综合五月婷婷啪啪| 一级二级色大片| 五月天中文字幕在线婷婷| 精品一区久热| 五月丁香久久综合| 这里只精品热在线18| 99热1| 99∨VTV| 丁香五月婷中字幕| 丁香五月 综合| 红桃91人妻爽人妻爽| 97九色| 天天成人综合视频| 91中文在线| 五月丁香婷婷狠狠操| www.婷婷| 五月婷婷丁香婷婷| 五月情综合| 色婷婷国产精品综合在线观看| 色婷婷影视| 久久丁香五月| 天天狠狠色| 国产精品香蕉| 婷婷五月AV| 激情图片五月天| 91精品综合久久久久久五月丁香| 大香蕉色婷婷伊人在线| 五月天停婷基地| 亚洲不卡| 婷婷成人丁香色情基地30| 婷婷丁香五月天中文字幕| 玖玖热视频| 97婷婷丁香| 五月婷婷五月| 久9热插入| 色婷婷五月在线| 99热99在线| 五月婷在线色视频| 亚洲综合在线播放| 国产精产国品一二三在观看| 99热欧美精品| 亚洲精品久久久久久久久久飞鱼| 中文字幕av久久爽| 99热综合| 五月亭亭狠狠| 五月婷婷丁香| 激情六月天婷婷| 色五月激情问网站| 天天做天天爱天天高潮| 香蕉久久国产AV一区二区| 日韩精品一曲二曲三曲四曲五曲| 日韩不卡DvD| www·五月天| 网站免费一站二站| 9精品久久999| 色~性~乱~伦~噜| er99免费视频在线| 丁香六月在线| 婷婷五月六月丁香| 五月天激情AAAA| 五月丁香激情婷婷| 色网站9| 精品99这里有| 精品人妻在线| 在线超碰免费| xx色综合| 五月丁香综合激情| 婷婷免费无马| 天天操天天操天天操天天操天天操天天操天天操天天操天天操 | 丁香五月天日韩无码| 99re6热在线精品视频播放速度| 五月婷婷丁香av| 亚洲最大视频| 日本一毛片| 五月色网| 青草视频在线播放| 99激情网| 伊人五月天在线| 婷五月天丁香婷五月| 亚洲婷婷五月草久| a在线观看| 97香蕉久久超级碰碰高清版| 99精品在这里| 亚洲日本三级片| 五月丁香WWW| 九九av| 国产午夜精品一区二区| 欧美成人性爱网| 狠狠色丁香乆乆| 久久久久久久久久久久久久人妻视频 | WWW,五月| 97超碰9久热婷婷热| 六月婷伊人| www久久久| 婷婷色五月大香蕉在线观看| 亚洲激情网| 美女被肏网站在线看| 午夜精品777| 亚洲综合激情五月久久| 婷婷丁香六月五月天| 色欲丁香| 99视频内射三四| 色综合区| 91精品丝袜久久久久久| 99视频在线精品| 日韩成人无码人妻| 色九网| 中文资源在线a | 人妻久久久久久久 | 六月色播| 婷婷九色| 99色婷婷视频| 婷婷五月天成人导航| 99碰碰| 色色色欧美| 亚洲色另类| 色频玖玖五月天| 高清无码网址| 天天操天天日天天爽| 亚洲黄网AV| 热成人网| 五月香蕉网| www.9797国产| 九九性视频| 丁香五月在线播放| 五月天久久www| 婷婷九九色| 天天天干夜夜夜操| 97色片| 婷婷狠狠干| 9999热精品在线免费播放| 怡红院AV亚洲一区二区三区H| 九九色99| 超级碰碰碰碰视频| 丁香婷婷激情| 天天爽日日爽夜夜爽| 丁香婷婷婷五月综合色情| 久久艹99| 99小精品| 欧美成人日韩| 久久女婷| 天天日,天天插| 久久婷丁香五月| 91中文在线| 色五婷婷| 综合婷婷| 97婷婷五月丁香| 天天插天天干| 深爱五月天婷综合| 4399伦理午夜| 国产精品久久久久久久久久免费| 夜夜爽天天爽| 欧日韩AV| 夜色综合网| 99熟女| 婷婷五月天第三页| 99热精品10| 日韩久久日| 久操操| 日本成人小说婷婷六月| Av大香蕉| 狠狠综合区| 91狠狠综合久久| 五月天激情www| 色婷婷六月性| 超碰高清在线| 麻豆观看夏晴子| 99日在线视频| 亚洲视频伍月婷婷| 九九精品片一| 婷婷丁香亚洲色综合91| 老司机视频lsj爱就色| 99热精品在线播放| 激情综合网五月激情网| 五月丁香在线国产 | 五月丁香偷拍| 色香蕉精品五夜婷| 五月亭亭开心网| 日本色爽| 婷婷激情五月色综合| 日日噜狠狠色综| 精品久久婷婷| 婷婷黄色网| 成人精品视频99在线观看免费| 欧美啪啪9| 99这里是精品| 五月婷婷综合色拍| 五月丁香六月婷婷,婷| 停停五月色宗合| 婷婷六月成人| 日本一級黃色一級片| 婷婷五月天综合网| 色区久久| 久久婷.com| 久久国产色| 婷婷情色激情| 99性感视频| 99热这只有| 国产亚洲99| 另类亚洲2| 97碰人人操| 丁香五月婷婷欧美成人色图| 午夜]香婷婷深深爱| 欧美久久一级内射wwwwww.| 五月天开心网| 欧美激情VA永久在线播放| 在线视频另类| 深夜男女福利刺激影院一区完整| 日本九九视频| www.maotanji.com| 欧美精品99| 婷婷月综合| 色呦呦美女| 日韩在线视频中文字幕| 综合AV在线| 丁香婷婷五月六月久久| 综合激情五月丁香| 色婷婷色99国产综合精品| 91碰碰| 深爱综合网| 五月天激情婷婷| 伊人五月天在线| 九九色色| 欧美成人AAA片一区国产精品 | 丁香五月天激情视频| AV人人操| 久久精彩视频| 婷婷碰碰| 久久久五月天网站| 黄色三级日本| 凹凸探花电影| 丁香婷婷色五月合集| 激情网婷婷婷| 五月婷婷激情| 婷婷丁香人妻天天爽| 五月婷婷色| ..真实国产乱子伦对白在线_欧| 九九色婷婷五月天| 综合久久久婷| 草草视频91| 伊人天天色| 欧美成人网99网| 久久伦乱| 五月丁香综合| 狠狠干狠狠操狠狠爱| 五月丁香激情综合六月涩涩爱| 狠狠久久婷五月| 2025中文在线视频字幕免费观看| 五月婷婷欧美激情| 丁香五月区| 亚洲精品色| 超碰无码老师| 国产精品成人在线| 都市激情小说婷婷| 久热 91| 成人精品视频99在线观看免费| 婷婷色综合中心站| 国产99久久久| 丁香五月婷婷俺也要去| 日良久久| 国产97在线日韩亚洲女人被黑人巨大| 99九无网码| 五月激情久久综合| 夜夜大香蕉婷婷丁香| 在线只有精品| 久久婷婷丁香五月宗合| 精品福利911| 五月天丁香综合久久国产| 九九综合| 婷婷五月激情欧美| www夜夜操wwwcon| 超碰AV在线| 精品国婬伦V无码久久久| 久久久久9| 久久思思精品| 双性美人被调教到喷水A片| 色色婷婷丁香五月天| 狠狠 婷婷| 五月天婷婷网站888| 久久99热网| 亚洲综合九九| 国产成人亚洲综合A∨婷婷| 在线另类| 婷婷综合色| 99精品免费欧美小视频| 免费无码毛片一区二区A片 | 第四色五月激情网| 97人人操| 色欲色香综合网站| 九九亚洲小视频| 日本久久网| 激情五月婷婷她| 五月丁香婷婷六月天| 狠狠色婷婷| 九月综合| 俺去也五月天| 91碰碰碰久久久久| 少妇人妻凹凸视频| 少妇高潮呻吟A片免费看软件| 26.uuu丁香五月婷婷| 噜噜久| 天天色中文字幕女优AV| 五月丁香久久综合精品| 99久久婷婷国产综合精品草原| 9精品在线| 天天做天天爱| 超碰色人妾| 另类五月激情| 韩国不卡AC视频| 日在线V视频在线播放| 五月婷婷基地| 丁香婷婷精品视频| 99久久这里只有精品| 色婷婷免费观看| 激情图片婷婷丁香五月| 九九偷拍网| 久久爱婷婷| 五月丁香趴趴| 丁香五月中文字幕色播| 六月激情婷婷综合| 久色大| 九色无码| 99自拍视频网站| 97人人操人人| 超碰国产在线| 综合激情开心五月| 夫妇交换刺激做爰| 久久9热好| 五月花成人网| 激情五月四色| 午夜五月天| 五月婷婷精品视频| 五月人妻婷婷视频| 亚洲婷婷久久综合| 亚洲精品无码久久| 色丁香五月婷婷婷| 久久在线视频免费观看| 丁香五月亚洲婷婷| 人妻中文av| 热久久这里只有精品| 97久久草草超级碰碰碰| 26uuu成人网| 五月天播播综合| 婷婷操无码| 五月天婷久精视频| 91久久久久久| 欧美丰满熟妇BBB久久久| 人人干AV| 五月婷婷九九久久| 久草婷婷| 婷婷深爱五月亚洲综合| 超碰免费人人肏| 五月婷婷深深爱| 婷婷五月色情天| 国产毛片精品一区二区色欲黄A片| 99久久综合精品五月天| 成人网丁香五月| 99久久极情精品一区| 日本在线视频手机播放五月婷| 日韩不卡123| 欧美精品99久久久| 国产精品美女久久久久AV超清| 五月丁香在线综合| 99超级碰免费视频| 亚洲xx在线| 狼友超碰| 婷五月丁香| 婷婷五月天性爱视频| 超碰人人操在线| 少妇激情五月婷婷| 久久久久久久久久久44| www.夜夜操| 久久色五月天综合网| 久久五月网| 五月天福利影院导航| 五月天激情四射网站| 99热20| 日韩在线成人电影| 免费观看欧美成人AA片爱我多深| 五月天综合久久| 伊人大香五月天| 丁香五月婷婷高清| 99久久综合| 99re6久热只有精品6在线直播| 色五月无码| 91精品综合久久久五月天| 婷婷激情综合网| 色五月婷婷网| 思思久久青草热| 婷婷五月天AV| 視频福利乱色| 狠狠爱深色婷婷综合| 日韩久热| 五月天天爱| 五月婷婷丁香五月亚洲色| 九九99香蕉在线视频播放| 国产精品扒开腿做爽爽爽A片唱戏| 丁香六月激情| 色深爱五月| 婷婷深爱五月亚洲综合| 99热都是精品| 伊人五月天| 婷婷五月AV| 六月丁香婷婷综合色播| 天堂中文国产| 91啪啪啪啪| 亚洲狠9| 欧美成人AAA片一区国产精品| 成人av免费观看| 丁香婷婷九月| av狠狠操| 五月天婷婷中文字幕在线播放| 亚洲色色在线| 五月天婷婷色在线视频免费观看 | 日韩aaaaa| 噜噜噜狠狠色综| 99色精品| 六月丁AV| 五月花丁香婷婷| 六月婷婷日| 五月激情丁香久久综合网| 亲子乱AV一区二区三区下载| 99.N在线视频| 国产中文字幕在线视频免费观看| 超碰天堂网| 色色色com| 超PEN精品在线| 九九在线热九九在线热99热| 亚洲日韩一页精品发布| 五月天婷婷影院| 丁香五月综合| 天天天天操| AV中文在线| 67194国产| 丁香六月激情综合| 国产精自产拍久久久久久蜜 | 六月激情婷婷色| 天天搞夜夜爽夜夜爽| 99re99在线看| 五月丁香综合激情在线观看| 五月激情五月丁香| 日本丁香五月婷婷| 五月丁香天堂网婷婷| 亚洲激情五月丁香久久久久| 99热这里有精品2| 激情丁香五月婷婷啪啪| 99re热视频这里只精品| 丁香五月婷婷在线观看| 九九性爱网| 久久作爱| 精品人妻一区二区| 国产精品扒开腿做爽爽爽A片唱戏| 丁香五月天激情综合| .精品久久久麻豆国产精品| 成人综合视频网址| 久久精品天| aaa久久| 婷婷六月丁香激情| 亚色网站小视频| 天天干天天操天天上| 亚洲最大五月天成人网| 香蕉人在线香蕉人在线 | 狠狠爱婷婷爱| 色婷婷av在线观看| 色欲AVV| 婷婷大乡焦噜噜| 久久九九99| va婷婷在线免费观看| 成人免费va| 亚洲色啪| 亚洲愉拍99热成人精品| 五月花激情网| 婷婷激情五月| 五月亭亭综合五码| 玖玖婷婷综合| 欧美色五月| 91久久九九| 久久婷婷六月综合| 久久机只有这里精品| 免费亚洲婷婷五月| 99ri精品| 日韩国产AV播放| 91丨九色丨白浆秘| 热久久99视频| 亚洲乱码w在线观看| 日本九九九九| 中文字幕婷婷在线| 精品婷婷五月天| 思思久久精品| 婷婷丁香熟妇综合网| 五月丁香 狠狠爱| 超碰在线人妻| 五月婷婷婷婷网| 深爱五月激情五月| 超碰在线94| 新99思思视频| 久9热视频| 麻豆AV一区二区三区| 香蕉操亚洲| 欧美日本一区二区三区| 久久草大香蕉| 奇米四色五月天| 日韩五月婷婷| 影音先锋91| 伊人婷婷福利网| 任你艹| 色色亚洲视频| 无人区码一码二码三码医生系列| 久久久久久久久久91| 婷婷五月天亚洲精品| 欧美久热| 伊人久热91| 婷婷色日本| 九九色精品| 99热一本久道| 五月丁香婷婷啪啪综合网| 久久综合爱| 亚洲色五月婷婷| 开心五月婷婷在线| 日日夜夜天天| 99热亚洲精品| 99精品在线观看视频| 成人在线观看精品| 久热这里只有精品在线观看 | 五月丁香在线| 五月天激情四射| 五月天久久91| 日韩国产AV播放| 色综合久久88色综合天天人守婷| 91九色网| 26UUU欧美激情一区二区| 日韩在线aaa| 中文字幕视频色婷婷| 99rewww| 久久五月婷| 97人人操人人| 亚洲综合另类| 久99久99精品免| 五月天亚洲色| 日韩国产AV播放| 欧美婷婷五月天综合| 激情又色又爽又黄的A片| 丁香五月天色| 夜夜撸夜夜骑| 婷婷久久综合| 丁香六月在线| 91Chinese在线| 久久大香蕉同僚| 日本精品干| 日本色视| 国内久久久精品99| 激情六月丁| 77777亚洲午夜久久| 99精品亚洲| 五月天色色色色色| 五月天综合在线观看视频| 综合网网欲色| 婷婷丁香五月网| 欧美日韩成人高清在线| 少妇人妻人伦A片| 六月久久婷婷| 久久综合干| 97色婷| 五月丁香综合| 五月丁香天堂网婷婷| 色吧婷婷五月亚洲| 综合一本道| 九九视屏| 91日本在线| 婷婷综合网| 色丁香久久| 六月丁香深深爱| 青青草青青草五月天| 啪啪六月婷婷| 亚洲黄3级片网站欧美| 大香蕉久久久久| 丁香5月激情网| 性做久久久久久久免费看| 丁香六月婷婷综合麻豆| 久久婷婷网址| 俺去也婷婷| 久久综合爱| 538在线精品| 丁香 婷婷 亚洲 熟女| 综合色吧| 天天干天天操天天拍| 五月婷婷,六月激情| 啪啪操网| 九九九热精品| 精品婷婷五月天| 99re资源在线视频导航| 久9视频免费播放| 九九国产视频| 美女久久婷婷| 99热这| 国产一区二区av免费| 五月婷婷丁香啪啪| 五月天激情久色| 99久久成人| www,色中色| 99热这里都是精品| 天天色图| 怡红院视频| 少妇激情五月天| 丁香五月六月综合激情| 91丨九色丨东北熟女| 狠狠操狠狠| 亚洲欧洲中文日韩久久AV乱码| 中文字幕日产A片在线看| 国产露脸150部国语对白| 久久综合99综合| 色综色网| 久久全色| 色www.con| 五月婷婷啪啪| 色黑鬼导航| 五月丁香成人版| 极品五月天| 亚洲情欲| 九九综合色综合| 五月婷婷六月丁香综合在线| 超碰AV在线| 5月丁香综合图区| 任你干线上免费视频有3吗| 美国不卡视频| 色播婷婷大香蕉| 丁香五月婷婷深爱综合激情| 欧美激情五月天在线观看| 日韩精品色| 色婷婷色99国产综合精品| 91色在线/日韩| 五月丁香大香蕉| 91热久88| 大香蕉人在线65| 激情小说五月天社区丁香| 婷婷丁香人妻| 综合五月天完整| 天天操B| 日产精品一线二线三线芒果| 99视频热99| 日韩在线观看亚洲| 五月丁香婷婷福利| 婷婷香五月综合激情| 久碰婷婷视频| 九九Av| 丁香婷婷激情四射五月| 婷婷99热| 天天在线久久综合| 五月丁香六月婷婷激情视频在线观看免费| 丁香五月天黄色片| 亚洲日韩一页精品发布| 男人視頻站| 五月丁香美女| 婷婷五月天中文字幕| 99视频自拍| 激情五月丁香五月色| 亚洲激情综| 久久伊人日日夜夜| 久久天堂| 精品夜夜澡人妻无码AV| 超碰网站在线观看| 丁香婷婷丁香五月欧美人| 天天操人人干| 六月丁香啪啪| 一起肏在线视频| 色综合播放| 久久精品系列| 国产av天堂| 青青草原伊人网| 婷婷久久夜| 综合网啪啪| 91狠狠色丁香婷婷综合久久狠丁香综合久久精品 | 国产熟妇的荡欲午夜视频| 婷婷色色欧美| 色五月开心五月激情五月| 极品人妻VideOssS人妻| 国产精品国产成人国产三级| 亭亭玉月丁香| 色婷婷六月综合| 五月停亭六月,六月停亭的英语| 天堂久久丁香| 五月丁香久久精品在线观看| 婷婷五月天激情网站| 人妻久久久久久| 五月久久婷婷天堂视频| 丁香五月久久综合| 天天插天天插天天插天天插| 91日综合欧美| 五月丁香久久久日婷婷久久婷婷日| 类似婷婷激情综合网站| 久久精品凹凸分类| 激情五月天婷婷图| www.狠狠| 天天干天天日蜜臀av| 久久精品爱爱| 日熟女| 奇米色大香蕉| 亚洲综合网激情小说| 淫视馆aV二区一区| www狠狠com| 综合激情深爱| 被强行糟蹋的女人A片| 97AV在线视频| 欧洲色| www.1024久久| 天天拍夜夜爽| 大香蕉人妻| 五月婷婷人人人操| 99色热| AV变态另类一区二区| www.思思99热| 99无码视频| 日日骑夜夜撸| 丁香五月天黄色片| 性爱人人网| 99思思| 91麻豆国产三级精品福利在线观看| 麻豆科斗777| 夜夜干夜夜操| av久热| 国产avapp 网| 六月丁香婷婷色狠狠久久| 婷婷五月天改成什么了| 成人在线日韩欧美| 亚洲第一色区| 五月天丁香婷婷久久九| 激情婷婷丁香五月| 激情久久久| 色婷婷五月天亚洲| 婷婷五月天精品| 午夜色婷婷| 大香蕉婷婷色| 96丁香六月婷婷蜜桃综合久久| 97色啪| 影音先锋 一区| 欧美婷婷成人| 色色丁香色五月| 开心激情播播五月天| 大香蕉视频婷婷| 夜夜操天天爽| 偷拍99在线视频观看| 色色综合网络| 在线超碰精品| 五月六月婷| 色五月婷婷1| 在线观看婷婷5月| 9久热在线视频精品| 婷婷丁香97| 婷婷丁香在线| 天天干天天干天天干| 婷婷五月天伊人在线| 丁香色色网| 狠狠色狠狠鲁| 一区二区三区四日本| 99国产性感视频| 成人 AV播放| 五月天亭亭俺也| www.97干视频| 91欧美日韩综合| 五月天激情综合网俺也去| 欧美日韩999| 婷婷久久六月天| 日B日潘金莲BB| 天天精品视频免费观看| 91疯狂操操操操| 99九色视频在线观看| 亚洲人成网亚洲欧洲无码久久| 91chinese在线| 五月婷婷激情色情网| 黄色av网站在线免费播放| 欧美激情综合五月色丁香| 人橾人| 欧洲亚洲精品| 操逼福利视频| 中文在线视频久9| 色狠狠综合网| 五月色亭丁香| 五月婷A V在线| 五月天啪啪啪| 大香蕉啪啪网| 国产看真人毛片爱做A片| 激情深爱五月| 五月丁香无码| 天天日天天插| cc精品国产性传播| 操操国产| 五月婷婷六月激情| 可以观看的AV| 五月丁香琪琪| 乱精品一区字幕二区| a久久免费视频| www99精品| 香蕉久久国产AV一区二区| 色五月激情五月天| 超碰99在线观看| 欧美午夜乱妇午夜福利| 五月丁香综合网| 狠狠色丁香五月婷巨| 丁香五月婷婷社区| 五月婷婷影| 中文字幕簧片| 欧美VA视频| 少妇性BBB搡BBB爽爽爽视頻| 色色com| 6月丁香婷婷激情|