音視頻入門-11-PNG文件格式詳解

* 音視頻入門文章目錄 *

PNG 文件格式解析

PNG 圖像格式文件由一個 8 字節(jié)的 PNG 文件署名域和 3 個以上的后續(xù)數(shù)據(jù)塊(IHDR、IDAT卸例、IEND)組成逸雹。

PNG 文件包括 8 字節(jié)文件署名(89 50 4E 47 0D 0A 1A 0A,十六進(jìn)制)掺炭,用來識別 PNG 格式。

用十六進(jìn)制查看器打開任意一個 PNG 文件凭戴,都是可以看到這樣的頭部:

png-hex-file-signture.png

PNG 定義了兩種類型的數(shù)據(jù)塊:一種是 PNG 文件必須包含涧狮、讀寫軟件也都必須要支持的關(guān)鍵塊(critical chunk);另一種叫做輔助塊(ancillary chunks)么夫,PNG 允許軟件忽略它不認(rèn)識的附加塊者冤。這種基于數(shù)據(jù)塊的設(shè)計,允許 PNG 格式在擴(kuò)展時仍能保持與舊版本兼容档痪。

數(shù)據(jù)塊總覽

下表就是 PNG 中數(shù)據(jù)塊的類別涉枫,關(guān)鍵數(shù)據(jù)塊部分突出顯示以區(qū)分:

數(shù)據(jù)塊符號 數(shù)據(jù)塊名稱 多數(shù)據(jù)塊 是否可選 位置限制
IHDR 文件頭數(shù)據(jù)塊 第一塊
cHRM 基色和白色點數(shù)據(jù)塊 在PLTE和IDAT之前
gAMA 圖像γ數(shù)據(jù)塊 在PLTE和IDAT之前
sBIT 樣本有效位數(shù)據(jù)塊 在PLTE和IDAT之前
PLTE 調(diào)色板數(shù)據(jù)塊 在IDAT之前
bKGD 背景顏色數(shù)據(jù)塊 在PLTE之后IDAT之前
hIST 圖像直方圖數(shù)據(jù)塊 在PLTE之后IDAT之前
tRNS 圖像透明數(shù)據(jù)塊 在PLTE之后IDAT之前
oFFs (專用公共數(shù)據(jù)塊) 在IDAT之前
pHYs 物理像素尺寸數(shù)據(jù)塊 在IDAT之前
sCAL (專用公共數(shù)據(jù)塊) 在IDAT之前
IDAT 圖像數(shù)據(jù)塊 與其他IDAT連續(xù)
tIME 圖像最后修改時間數(shù)據(jù)塊 無限制
tEXt 文本信息數(shù)據(jù)塊 無限制
zTXt 壓縮文本數(shù)據(jù)塊 無限制
fRAc (專用公共數(shù)據(jù)塊) 無限制
gIFg (專用公共數(shù)據(jù)塊) 無限制
gIFt (專用公共數(shù)據(jù)塊) 無限制
gIFx (專用公共數(shù)據(jù)塊) 無限制
IEND 圖像結(jié)束數(shù)據(jù) 最后一個數(shù)據(jù)塊

我們目前只需關(guān)注關(guān)鍵數(shù)據(jù)塊即可。

數(shù)據(jù)塊中有 4 個關(guān)鍵數(shù)據(jù)塊:

  • 文件頭數(shù)據(jù)塊 IHDR(header chunk):包含有圖像基本信息腐螟,作為第一個數(shù)據(jù)塊出現(xiàn)并只出現(xiàn)一次愿汰。
  • 調(diào)色板數(shù)據(jù)塊 PLTE(palette chunk):必須放在圖像數(shù)據(jù)塊之前困后。
  • 圖像數(shù)據(jù)塊 IDAT(image data chunk):存儲實際圖像數(shù)據(jù)。PNG 數(shù)據(jù)允許包含多個連續(xù)的圖像數(shù)據(jù)塊衬廷。
  • 圖像結(jié)束數(shù)據(jù) IEND(image trailer chunk):放在文件尾部摇予,表示 PNG 數(shù)據(jù)流結(jié)束。

數(shù)據(jù)塊連起來吗跋,大概這個樣子:

PNG 標(biāo)識符 PNG 數(shù)據(jù)塊(IHDR) PNG 數(shù)據(jù)塊(其他類型數(shù)據(jù)塊) PNG 結(jié)尾數(shù)據(jù)塊(IEND)

數(shù)據(jù)塊結(jié)構(gòu)

PNG 文件中侧戴,每個數(shù)據(jù)塊(比如IHDR,IDAT等)由4個部分組成:

名稱 字節(jié)數(shù) 說明
Length (長度) 4 字節(jié) 指定數(shù)據(jù)塊中數(shù)據(jù)域的長度跌宛,其長度不超過(2^31-1)字節(jié)
Chunk Type Code (數(shù)據(jù)塊類型碼) 4 字節(jié) 數(shù)據(jù)塊類型碼由 ASCII 字母(A-Z和a-z)組成
Chunk Data (數(shù)據(jù)塊數(shù)據(jù)) 可變長度 存儲按照 Chunk Type Code 指定的數(shù)據(jù)
CRC (循環(huán)冗余檢測) 4 字節(jié) 存儲用來檢測是否有錯誤的循環(huán)冗余碼
  • CRC(cyclic redundancy check) 域中的值是對 Chunk Type Code 域和 Chunk Data 域中的數(shù)據(jù)進(jìn)行計算得到的酗宋。
  • 注意:Length 值的是除:length 本身,Chunk Type Code疆拘,CRC 外的長度本缠,也就是 Chunk Data 的長度。

數(shù)據(jù)塊-文件頭數(shù)據(jù)塊 IHDR

它包含 PNG 文件中存儲的圖像數(shù)據(jù)的基本信息入问,并要作為第一個數(shù)據(jù)塊出現(xiàn)在 PNG 數(shù)據(jù)流中丹锹,而且一個 PNG 數(shù)據(jù)流中只能有一個文件頭數(shù)據(jù)塊。

文件頭數(shù)據(jù)塊由 13 字節(jié)組成:

域的名稱 字節(jié)數(shù) 說明
Width 4 bytes 圖像寬度芬失,以像素為單位
Height 4 bytes 圖像高度楣黍,以像素為單位
Bit depth 1 byte 圖像深度: 索引彩色圖像:1,2棱烂,4或8 灰度圖像:1租漂,2,4颊糜,8或16 真彩色圖像:8或16
ColorType 1 byte 顏色類型:0:灰度圖像, 1哩治,2,4衬鱼,8或16 2:真彩色圖像业筏,8或16 3:索引彩色圖像,1鸟赫,2蒜胖,4或8 4:帶α通道數(shù)據(jù)的灰度圖像,8或16 6:帶α通道數(shù)據(jù)的真彩色圖像抛蚤,8或16
Compression method 1 byte PNG Spec 規(guī)定此處總為 0台谢,表示使用壓縮方法(LZ77派生算法)
Filter method 1 byte PNG Spec 規(guī)定此處總為 0,濾波器方法
Interlace method 1 byte 隔行掃描方法:0:非隔行掃描 1: Adam7(由Adam M. Costello開發(fā)的7遍隔行掃描方法)

用十六進(jìn)制查看器打開一個 PNG 文件:

png-hex-ihdr.png
十六進(jìn)制 說明
00 00 00 0D 數(shù)據(jù)塊長度 13 字節(jié)
49 48 44 52 數(shù)據(jù)塊類型碼 “IHDR” 的 ASCII 字母
00 00 04 1D 圖像寬度 1053
00 00 02 B3 圖像高度 691
08 圖像深度 8
06 帶α通道數(shù)據(jù)的真彩色圖
00 壓縮方法
00 濾波器方法
00 隔行掃描方法:00非隔行掃描
52 C3 75 3A CRC (循環(huán)冗余檢測)

數(shù)據(jù)塊-調(diào)色板數(shù)據(jù)塊 PLTE

包含有與索引彩色圖像(indexed-color image)相關(guān)的彩色變換數(shù)據(jù)岁经,它僅與索引彩色圖像有關(guān)朋沮,而且要放在圖像數(shù)據(jù)塊(image data chunk)之前。

PLTE 數(shù)據(jù)塊是定義圖像的調(diào)色板信息缀壤,PLTE 可以包含 1~256 個調(diào)色板信息樊拓,每一個調(diào)色板信息由 3 個字節(jié)組成:

顏色 字節(jié) 意義
Red 1 byte 0 = 黑色, 255 = 紅
Green 1 byte 0 = 黑色, 255 = 綠色
Blue 1 byte 0 = 黑色, 255 = 藍(lán)色
  • 調(diào)色板的長度應(yīng)該是 3 的倍數(shù)朦蕴,否則甩恼,這將是一個非法的調(diào)色板愉舔。

  • 對于索引圖像笨使,調(diào)色板信息是必須的樱溉,調(diào)色板的顏色索引從 0 開始編號疫向,然后是 1襟雷、2……冈止,調(diào)色板的顏色數(shù)不能超過色深中規(guī)定的顏色數(shù)(如圖像色深為 4 的時候岳瞭,調(diào)色板中的顏色數(shù)不可以超過 2^4=16)拥娄,否則,這將導(dǎo)致 PNG 圖像不合法瞳筏。

  • 真彩色圖像和帶 α 通道數(shù)據(jù)的真彩色圖像也可以有調(diào)色板數(shù)據(jù)塊稚瘾,目的是便于非真彩色顯示程序用它來量化圖像數(shù)據(jù),從而顯示該圖像姚炕。

用十六進(jìn)制查看器打開一個索引圖像 PNG 文件:

png-indexed-color-hex-plte.png
十六進(jìn)制 說明
00 00 00 27 數(shù)據(jù)塊長度 39 字節(jié)
50 4C 54 45 數(shù)據(jù)塊類型碼 “PLTE” 的 ASCII 字母
B7 00 34 FF 99 00 60 00 73 FF 0F 00 FF ED 00 09 00 B2 FF 66 00 FF 3B 00 E2 00 15 8B 00 54 FF C1 00 33 00 99 FF FF 00 調(diào)色板顏色 13 個
48 29 75 2C CRC (循環(huán)冗余檢測)

預(yù)覽調(diào)色板中的顏色:

indexed-color-plte-colors.png

數(shù)據(jù)塊-圖像數(shù)據(jù)塊 IDAT

它存儲實際的數(shù)據(jù)摊欠,在數(shù)據(jù)流中可包含多個連續(xù)順序的圖像數(shù)據(jù)塊。

IDAT 存放著圖像真正的數(shù)據(jù)信息柱宦,因此些椒,如果能夠了解 IDAT 的結(jié)構(gòu),我們就可以很方便的生成 PNG 圖像掸刊。

用十六進(jìn)制查看器打開一個索引圖像 PNG 文件:

png-hex-idat.png
十六進(jìn)制 說明
00 00 00 D3 數(shù)據(jù)塊長度 211 字節(jié)
49 44 41 54 數(shù)據(jù)塊類型碼 “IDAT” 的 ASCII 字母
78 9C ...... 壓縮的數(shù)據(jù) 211 字節(jié)免糕,LZ77 派生壓縮方法
52 98 5D 9D CRC (循環(huán)冗余檢測)

圖像數(shù)據(jù)塊 IDAT 細(xì)節(jié)在本文下半部分有詳細(xì)分析

數(shù)據(jù)塊-圖像結(jié)束數(shù)據(jù) IEND

它用來標(biāo)記 PNG 文件或者數(shù)據(jù)流已經(jīng)結(jié)束,并且必須要放在文件的尾部忧侧。

如果我們仔細(xì)觀察 PNG 文件石窑,我們會發(fā)現(xiàn),文件的結(jié)尾 12 個字符看起來總應(yīng)該是這樣的:

00 00 00 00 49 45 4E 44 AE 42 60 82

用十六進(jìn)制查看器打開一個 PNG 文件:

png-hex-iend.png

由于數(shù)據(jù)塊結(jié)構(gòu)的定義蚓炬,IEND 數(shù)據(jù)塊的長度總 是 0(00 00 00 00松逊,除非人為加入信息),數(shù)據(jù)標(biāo)識總是 IEND(49 45 4E 44)肯夏,因此棺棵,CRC 碼也總是 AE 42 60 82。

圖像數(shù)據(jù)塊 IDAT 細(xì)節(jié)

IDAT 壓縮數(shù)據(jù)細(xì)節(jié)

PNG Spec 壓縮算法部分:

PNG compression method 0 is deflate/inflate compression with a sliding window (which is an upper bound on the distances appearing in the deflate stream) of at most 32768 bytes. Deflate compression is an LZ77 derivative [ZL].

Deflate-compressed datastreams within PNG are stored in the "zlib" format, which has the structure:

- zlib compression method/flags code    1 byte
- Additional flags/check bits   1 byte
- Compressed data blocks    n bytes
- Check value   4 bytes

Further details on this format are given in the zlib specification [RFC-1950].
  • PNG 使用 DEFLATE 壓縮算法熄捍。
  • DEFLATE 是同時使用了 LZ77 算法與哈夫曼編碼(Huffman Coding)的一個無損數(shù)據(jù)壓縮算法烛恤。
  • DEFLATE 壓縮的數(shù)據(jù)以 zlib 格式存儲。
    zlib(RFC1950):一種格式余耽,是對 deflate 進(jìn)行了簡單的封裝缚柏,他也是一個實現(xiàn)庫(delphi中有zlib,zlibex)
    gzip(RFC1952):一種格式,也是對 deflate 進(jìn)行的封裝碟贾。

    gzip = gzip 頭 + deflate 編碼的實際內(nèi)容 + gzip 尾
    zlib = zlib 頭 + deflate 編碼的實際內(nèi)容 + zlib 尾

提取&解壓 IDAT 中壓縮數(shù)據(jù)

Windows 上可以用 [hexeditor](https://www.hhdsoftware.com/free-hex-editor)
Mac 上可以用 [hexfiend](http://ridiculousfish.com/hexfiend/)币喧、[Hopper Disassembler](https://www.hopperapp.com/)
png-hex-idat-data-extract.png

使用 zlib 解壓 78 9C ...... 壓縮的數(shù)據(jù)字節(jié):

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "zlib.h"

int main() {
    FILE *inFile = fopen("/Users/staff/Desktop/indexed-color-image.data", "rb");
    FILE *outFile = fopen("/Users/staff/Desktop/indexed-color-image-uncompress.data", "wb");
    
    fseek(inFile, 0L, SEEK_END);
    long size = ftell(inFile);
    fseek(inFile, 0L, SEEK_SET);

    uint8_t dataBuf[size];
    fread(dataBuf, size, 1, inFile);
    printf("壓縮文件大泄煊颉:%ld\n", size);

    uint8_t destBuf[1500000]={0};
    uint32_t destLen = 0;

    uncompress(destBuf, &destLen, dataBuf, size);
    printf("解壓后大小:%d\n", destLen);

    fwrite(destBuf, destLen, 1, outFile);

    fflush(outFile);
    fclose(inFile);
    fclose(outFile);

    return 0;
}
png-hex-idat-uncompress.png

png-hex-idat-uncompress-contrast.png

分析解壓后的數(shù)據(jù)

PNG Spec 7.1 Integers and byte order

All integers that require more than one byte shall be in network byte order (as illustrated in figure 7.1): the most significant byte comes first, then the less significant bytes in descending order of significance (MSB LSB for two-byte integers, MSB B2 B1 LSB for four-byte integers). The highest bit (value 128) of a byte is numbered bit 7; the lowest bit (value 1) is numbered bit 0. Values are unsigned unless otherwise noted. Values explicitly noted as signed are represented in two's complement notation.
  • PNG 使用網(wǎng)絡(luò)字節(jié)序 大端字節(jié)序(Big Endian)杀餐。

PNG Spec 7.2 Scanlines

In PNG images of colour type 0 (greyscale) each pixel is a single sample, which may have precision less than a byte (1, 2, or 4 bits). These samples are packed into bytes with the leftmost sample in the high-order bits of a byte followed by the other samples for the scanline.

In PNG images of colour type 3 (indexed-colour) each pixel is a single palette index. These indices are packed into bytes in the same way as the samples for colour type 0.
  • PNG 圖像深度小于 1 字節(jié)干发,將會被 packed into bytes

PNG Spec 7.3 Filtering

PNG allows the scanline data to be filtered before it is compressed. Filtering can improve the compressibility of the data. The filter step itself results in a sequence of bytes of the same size as the incoming sequence, but in a different representation, preceded by a filter type byte. Filtering does not reduce the size of the actual scanline data. All PNG filters are strictly lossless.

Different filter types can be used for different scanlines, and the filter algorithm is specified for each scanline by a filter type byte. The filter type byte is not considered part of the image data, but it is included in the datastream sent to the compression step. An intelligent encoder can switch filters from one scanline to the next. The method for choosing which filter to employ is left to the encoder.
  • 每一掃描行前有一字節(jié)用于指定過濾器類型史翘。

PNG Spec Filters:

Filtering transforms the PNG image with the goal of improving compression. PNG allows for a number of filter methods. All the reduced images in an interlaced image shall use a single filter method. Only filter method 0 is defined by this International Standard. Other filter methods are reserved for future standardization (see 4.9 Extension and registration). Filter method 0 provides a set of five filter types, and individual scanlines in each reduced image may use different filter types.
枉长。。琼讽。必峰。。钻蹬。
  • 文件頭數(shù)據(jù)塊 IHDR 中 Filter method 過濾方法只能是 0吼蚁。
  • Filter method=0 定義了 5 種 Filter Type 過濾器類型: 0:None1:Sub问欠、2:Up肝匆、3:Average4:Paeth顺献。

當(dāng) PNG 圖片是索引圖像時(下圖數(shù)據(jù):圖像深度: 4 尺寸 256X256 過濾器類型: 0:None 隔行掃描方法:0:非隔行掃描):

indexed-color-image.png

png-indexed-color-uncompress-data.png
  • 每個高亮區(qū)域前面一個字節(jié) 00 代表 過濾器類型 : 0:NonePNG Spec 7.3 Filtering】【 PNG Spec Filters】术唬。
  • 如果高亮區(qū)域前面一個字節(jié)不是 00,高亮區(qū)將不是掃描行索引數(shù)據(jù)滚澜,需要參考 【PNG Spec 9.2 Filter types for filter method 0
  • 每種顏色高亮顯示的部分 128 字節(jié) 是一個掃描行顏色索引數(shù)據(jù)粗仓,因為 圖像深度:4,所以每個字節(jié)代表兩個顏色索引 【PNG Spec 7.2 Scanlines】设捐。
  • 如字節(jié) 55 是十六進(jìn)制借浊,二進(jìn)制為 01010101,前四 bit 位代表一個顏色索引 0101 十進(jìn)制為 5萝招,后四 bit 位代表一個顏色索引 0101 十進(jìn)制為 5 蚂斤。

當(dāng) PNG 圖片是真彩圖像時(下圖數(shù)據(jù):圖像深度: 8 尺寸 70X70 過濾器類型: 0:None 隔行掃描方法:0:非隔行掃描):

true-color-image.png

png-true-color-uncompress-data.png
  • 每個高亮區(qū)域前面一個字節(jié) 00 代表 過濾器類型 : 0:NonePNG Spec 7.3 Filtering】【 PNG Spec Filters】。
  • 如果高亮區(qū)域前面一個字節(jié)不是 00槐沼,高亮區(qū)將不是掃描行顏色數(shù)據(jù)曙蒸,需要參考 【PNG Spec 9.2 Filter types for filter method 0
  • 每種顏色高亮顯示的部分 210 字節(jié) 是一個掃描行顏色數(shù)據(jù),因為 真彩圖片 圖像深度:8岗钩,所以每三個字節(jié)代表一個像素顏色纽窟。
  • 如字節(jié) FF 00 00,代表一個像素 RGB 顏色兼吓。

More

下一步臂港,將用代碼手動生成一張 PNG 圖片,文章目錄:* 音視頻入門文章目錄 *

所有可能存在問題的答案:PNG Specification审孽。


代碼:
demos/demos-zlib

參考資料:

PNG 文件格式詳解

PNG县袱、JPEG、BMP等幾種圖片格式詳解(一)—— PNG

詳解PNG文件結(jié)構(gòu)

《PNG文件格式》(二)PNG文件格式分析

圖片知識梳理(一): PNG文件結(jié)構(gòu)

隱寫技巧——利用PNG文件格式隱藏Payload

Portable Network Graphics (PNG) Specification and Extensions

gzip,deflate,zlib辨析

Zlib庫的安裝與使用

本文由博客一文多發(fā)平臺 OpenWrite 發(fā)布佑力!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末式散,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子打颤,更是在濱河造成了極大的恐慌暴拄,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瘸洛,死亡現(xiàn)場離奇詭異揍移,居然都是意外死亡次和,警方通過查閱死者的電腦和手機(jī)反肋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來踏施,“玉大人石蔗,你說我怎么就攤上這事〕┬危” “怎么了养距?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長日熬。 經(jīng)常有香客問我棍厌,道長,這世上最難降的妖魔是什么竖席? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任耘纱,我火速辦了婚禮,結(jié)果婚禮上毕荐,老公的妹妹穿的比我還像新娘束析。我一直安慰自己,他們只是感情好憎亚,可當(dāng)我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布员寇。 她就那樣靜靜地躺著,像睡著了一般第美。 火紅的嫁衣襯著肌膚如雪蝶锋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天什往,我揣著相機(jī)與錄音牲览,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛第献,可吹牛的內(nèi)容都是我干的贡必。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼庸毫,長吁一口氣:“原來是場噩夢啊……” “哼仔拟!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起飒赃,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤利花,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后载佳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體炒事,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年蔫慧,在試婚紗的時候發(fā)現(xiàn)自己被綠了挠乳。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡姑躲,死狀恐怖睡扬,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情黍析,我是刑警寧澤卖怜,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站阐枣,受9級特大地震影響马靠,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蔼两,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一甩鳄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧宪哩,春花似錦娩贷、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至品抽,卻和暖如春储笑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背圆恤。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工突倍, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓羽历,卻偏偏與公主長得像焊虏,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子秕磷,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容