2013年3月26日火曜日

本日のげんなり TIFF編

 今日は参りました。 TIFFGetField という関数には、前回もやられているんですが、今回も、こてんこてんにやっつけられました。 TIFFTAG_GDAL_NODATA というタグの値を取得したくて、GDALのGeoTIFFパートを参考にコードを組んだら SIGSEGVの嵐。は〜 SIGSEGV、どんどん、ほぇー SIGSEGV、どんどん、ハイヤー SIGSEGV バンバン。
   char* pszText = NULL;
    if( TIFFGetField( hTIFF, TIFFTAG_GDAL_NODATA, &pszText ) )
    {
        bNoDataSet = TRUE;
        dfNoDataValue = CPLAtofM( pszText );
    }
突っ込んで面倒を見ていくと libtiff の tif_dir.c の int _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap) という関数でお亡くなりになっている事が判明しました。
  // なんと、field_passcount > 0 が成立しているので
  if (fip->field_passcount) {
    if (fip->field_readcount == TIFF_VARIABLE2) {
      // pszText にデータサイズが格納されて
      *va_arg(ap, uint32*) = (uint32)tv->count;
    } else  /* Assume TIFF_VARIABLE */ {
      *va_arg(ap, uint16*) = (uint16)tv->count;
    }
    // ありもしない第2の可変引数に値が格納されて
    // ここであぼ~ん 
    *va_arg(ap, void **) = tv->value;
    ret_val = 1;
  }
(゚∀゚)アヒャ(゚∀゚)アヒャ。関数の仕様というか、TAGの仕様が変わっとるがなwww 知らねぇよヽ(`Д´)ノウワァァァン!! と言いながらコードを修正
   uint32_t textLen = 0;
   char* pszText = NULL;
    if( TIFFGetField( hTIFF, TIFFTAG_GDAL_NODATA, &textLen, &pszText ) )
    {
        bNoDataSet = TRUE;
        dfNoDataValue = CPLAtofM( pszText );
    }
あれれ?まだまだ SIGSEGV おほー、どんどん SIGSEGV ひ~~。 更に突っ込んで面倒を見ていくと、同じく tif_dir.c にて
  // えっ?今度は、field_passcount == 0
  if (fip->field_passcount) {
    //...
  } else if (fip->field_tag == TIFFTAG_DOTRANGE
     && strcmp(fip->field_name,"DotRange") == 0) {
    //...
  } else {
    // そして、field_type == TIFF_ASCII なので
    if (fip->field_type == TIFF_ASCII
      || fip->field_readcount == TIFF_VARIABLE
      || fip->field_readcount == TIFF_VARIABLE2
      || fip->field_readcount == TIFF_SPP
      || tv->count > 1) {
          // 第1引数 uint32_t にポインタ値が代入され
          // 第2引数が放置プレーで、最終的にあぼ~ん
          *va_arg(ap, void **) = tv->value;
          ret_val = 1;
    } else {
      //...
 隊長!エスパーじゃないから、推定できましぇんヽ(`Д´)ノウワァァァン!!  ということで、とりあえず、2引数を取る形態で対処しました。
    if (fip->field_type == TIFF_ASCII
      || fip->field_readcount == TIFF_VARIABLE
      || fip->field_readcount == TIFF_VARIABLE2
      || fip->field_readcount == TIFF_SPP
      || tv->count > 1) {
          if( (tag == TIFFTAG_GDAL_METADATA) || (tag == TIFFTAG_GDAL_NODATA) ) {
             *va_arg(ap, uint32*) = (uint32)strlen(tv->value);
          }
          *va_arg(ap, void **) = tv->value;
          ret_val = 1;
    } else {
 もの凄く疲れた。

0 件のコメント: