AlpacaTech Blog

ゲーム作りたい系草食動物の備忘録

libpngでエラー出たメモ

 

結論

結論から書くと

8bit深度しか対応してなかったのに

16bit深度のpngを読み込んでバッファオーバーフローしてました。

 (iPhone8等のスクリーンショットは何故か64bitカラー)

 

問題

今まで問題なく動作していたpng読み込みでエラーが発生しました。

初回例外が 0x00007FF81B0B775F (ntdll.dll) で発生しました (Test.exe 内): 0xC0000374: ヒープは壊れています。 (パラメーター: 0x00007FF81B1186B0)。
というエラー。f:id:alpacatech:20171024170219p:plain

デバッガで見たらpng_read_image で例外発生している模様


原因

pngファイルのビット深度が8bitでなく16bitだった。
8bitしか考慮していないコードを書いていたので
png_read_imageでバッファーオーバーフローしていました。

 

対策

受け取るバッファを16bitサイズに対応すると問題なくなりました。


データ内容について

今回の16bitカラーの場合、
トルエンディアンでなくビッグエンディアンなので入れ替える必要がある。

8bitカラーで受ける場合はそのまま&0xFFで取得で問題ない。

 

 OpenCVで16bit深度の画像を読み込んだ場合

OpenCV2.4.11で
16bitpngをcv::imreadした場合は、
flags=1 の場合 CV_8U(8bitで読み込み)
flags=-1の場合 CV_16U(16bitで読み込み)
で取得できていました。

 

64bit pngはどうやって作成されていたのか?

 iPhone/iPadでスクショをとった場合、

今までは24bit pngで保存されていました。

iPhone8 iOS11でスクショをとると64bit pngで保存されるようです。

iPhoneSE iOS11でスクショは、24bit pngでした。

 

アプリ利用者で

iPhoneのスクショを読み込んだ際、

アプリが落ちる、表示されない、色がおかしい等の現象が起こる場合、

24か32bitに変換すると動作すると思われます。