我目前正在開發基於png文件格式的專有文件格式。我到目前爲止已完成,除非它不起作用:-p我實現的deflate解壓縮器就像一個魅力一樣工作,但png解碼器不想很好地執行,所以我查看了原始png文件。IDAT大塊的PNG文件格式
該標準說明,在IDAT頭後,壓縮數據緊隨其後。因此,由於數據是放氣流,IDAT之後的第一個字符是0x78 == 01111000,這意味着,模式一塊(未壓縮),而不是最後一個。
奇怪 - 雖然我很難想象PNG編碼器不使用動態霍夫曼編碼來壓縮濾波後的原始圖像數據。放氣標準表示當前字節的其餘部分在模式1中被跳過。
所以接下來的四個字節表示未壓縮塊的大小及其一個補碼。 但0x59FD不是0xECDA的補碼。即使我搞砸了字節順序:0xFD59也不是0xDAEC的補碼。
那麼,淘汰賽字節緊隨其後。 0x97被認爲是未壓縮但仍然過濾的原始png圖像數據的第一個字節,因此必須是filtertype。但0x97 == 10010111不是有效的過濾器類型。事件,如果我擰了位打包訂單11101001 == 0xe9仍然沒有有效的過濾器類型。
因爲我能夠使用我的deflate解壓縮器實現來擴充所有類型的文件,所以我懷疑我的一些誤解是認識到PNG標準。
我一遍又一遍地讀了RFC 2083,但我在這裏看到的數據與RFC不匹配,它對我沒有意義,必須有一個缺失的部分!
當我看下面的字節時,實際上我看不到有效的過濾器類型字節,這使我認爲過濾後的png數據流畢竟是壓縮的。
如果0x78(IDAT之後的第一個字節)從MSB讀到LSB,但RFC 1951另有說明,這將是有意義的。另一個想法(更可能是我)是在IDAT字符串和壓縮deflate流的開始之間存在一些數據,但RFC 2083另有說明。佈局是清楚
4字節大小 4字節ChunkName(IDAT) [大小]字節(壓縮的放氣流) 4字節CRC校驗
所以IDAT後的第一個字節必須是壓縮的放氣流的第一個字節 - 表示模式1未壓縮的數據塊。這意味着,0x97必須是未壓縮但過濾的PNG圖像數據的第一個字節 - 這意味着0x97是第一行的filtertype - 這是無效的...
我只是不明白,我是愚蠢的還是什麼??
總結: 可能性1: 有IDAT和,如果使是真實的,沒有在RFC2083也不在任何書meantioned壓縮放氣流的有效開始之間的某個其它數據I閱讀有關圖像壓縮。
可能性2: 數0x78被解釋MSB - > LSB其將指示一個模式3塊(動態霍夫曼編碼),但是這與RF1951大約是位打包非常明確矛盾:(LSB - > MSB)
我已經知道了,缺少的部分必須有一些非常愚蠢的,我會覺得urgend需要賣掉我的靈魂,如果有隻在堆棧溢出:-P
我沒有意識到deflate流被包裝在一個zlib容器中。我認爲它是一個純粹的縮小流。所以我現在簡單地跳過了兩個字節,並且瞧 - png進口商的工作! :-) 非常感謝! – Silverdust 2014-10-01 23:50:55