Tuesday, December 01, 2009

Stream Read Error

這兩個星期, 由於撰寫 IPCDMC範例程式 的緣故, 遭遇一個以前未曾發生過的問題: 我用 Photoshop CS 所儲存的 bmp 檔案, 用 C++ Builder 6 開啟, 會發生 Stream read error, 如下圖:



我的第一個反應也是問 Google 大神, 順利找到了一些相關討論[1, 2, 3], 但始終沒有人可以指出確切的問題點。

昨天晚上, 由於 對比度擴展(Contrast Stretching)範例程式 的實驗需要造一張低對比度的影像, 而我的電腦又只有灌 Photoshop CS, 因此逼得我一定要面對這個問題。



由於錯誤訊息是 Stream read error, 因此, 我直接排除是程式撰寫上的問題, 直接從有問題的 bmp 影像開始研究。為了比較, 我將可以順利用 C++ Builder 6 開啟的檔案 Carnivore.bmp 用 Photoshop CS 另存新檔 CarnivorePSCS.bmp, 然後再分別用 PSPad 用 Hex editor 開啟, 比較兩個檔案的異同。

BCB6-PS-bmp-StreamReadError.txt 在這個檔案中, 我列出了兩個 bmp 檔頭資料以供比對, 我發現兩個檔頭資料中, 只有第 34-37 位元組的影像原始大小有差異, 可以順利開啟的 Carnivore.bmp 並沒有儲存影像大小到檔頭之中, 而 CarnivorePSCS.bmp 則是存放了 0200 0C00 的資料, 我當下用 PSPas 將第 34-37 位元組修改成 0000 0000, 果然 CarnivorePSCS.bmp 就可以用 C++ Builder 6 順利開啟了。

接下來, 我當然先去完成 對比度擴展(Contrast Stretching)範例程式 的實驗, 把低對比度的彩色影像自動處理成高對比度的影像, 並完成 部落格範例程式的文章

今天, 在往學校的路上, 我一直在思考為何 Photoshop CS 會多此一舉把影像大小的值放進去, 而且還造成 C++ Builder 6 無法讀取? 難道 Photoshop CS 會把影像大小 Width * Height * BitCount / 8 這麼簡單的數學計算錯誤嗎?

晚上回到家後, 把 0200 0C00 換算, 得到 786434, 然而影像大小

 Width * Height * BitCount / 8
= 512 * 512 * 24 / 8
= 786432

果然就如同自己所推測的一樣, 影像大小差了 2 個 bytes。

我最後的一個實驗是將 CarnivorePSCS.bmp 的第 34-37 位元組 (影像大小) 修改成 0000 0C00, 果然 也可以用 C++ Builder 6 順利開啟。

真相大白了 !