2013年2月7日木曜日

本日のバグTIFF編

本日のバグの紹介です。
TIFF の情報を調べるクラスを作っていて
class tiffinfo {
private:
  uint32_t image_width_;
  uint32_t image_height_;
  uint16_t tile_width_;
  uint16_t tile_height_;
  uint16_t samples_per_pixel_;
  ...
};
みたいなメモリレイアウトになってたんですわ。
LibTIFFのAPI 設計には、いろいろと不満たらたらで、かなりフラストレーションたまってます。この中に TIFF の TAG値を取得するAPIがあって、
extern int TIFFGetField(TIFF* tif, uint32 tag, ...);
という形式なんです。
で、いろんなタグがあるんですが、サイズがよくわからない。まぁ、サイズがよくわからないのは、ドキュメントをちゃんと読んでないのバレバレなんですけどね(>_<)
  if( 1 != TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samples_per_pixel_) ) {
    ...
  }
  ...
  TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tile_width_);
  TIFFGetField(tif, TIFFTAG_TILELENGTH, &tile_height_);
はい、勘の良い人ならわかったでしょうか?実は、tile_width_ と tile_height_ は、uint32_t じゃないといかんのでした。
まずい事に、リトル・エンディアンだと、その箇所のサイズを間違った事を簡単に気が付きません。
ウィンドウズだとアライメントが 32bit なんで、この問題は表面化しません。ndk で開発してると、アライメントが 16bit あたりだったんでしょうね〜。tile_height_ を読みだした瞬間に samples_per_pixel_ のメモリ領域に上位 16bit の値 0 で上書きですわ。 怖い怖い。

0 件のコメント: