サイトマップ
お知らせ、メモ
案内板
うちのヘッドライン
 




トップ  >  ライブラリ豆知識  >  libtiff豆知識  >  セパレートタイプのTIFF読み込み

セパレートタイプのTIFF読み込み

通常のカラー画像フォーマットはRGBRGB...というようにデータが並んでいますが、 セパレートタイプのTIFFとは、Rが1行、Gが1行、Bが1行というように並んでいるものです。 リモセン用語で言うと、通常のカラー画像はBIP、セパレートタイプはBILということになります。

このフォーマットの場合、libtiffでの挙動は通常のカラー画像と以下のような違いがあります。

  • TIFFScanlineSize()関数は通常の画像は画像の横幅*色数の値を帰すが、 セパレートの場合は画像の横幅の値
  • TIFFReadScanline()関数は1色分のデータを読み込む
  • TIFFRasterScanlineSize()関数ならば同じ値を返す

見るからにめんどくさそうなフォーマットですが、 TIFFReadScanline()関数に便利な4番目の引数というのがあります。 これはセパレートタイプの場合にのみ有効な引数で、読み込む色(サンプル)を指定するというものです。 これを使って、下記のサンプルコードではセパレートファイルから通常のフォーマットに書き出しています。

ちなみに、TIFFベースラインの仕様では、セパレートタイプのフォーマットは非推奨であり、 ソフトウェアはセパレートタイプのTIFFファイルを読み込む義務は無いそうです。 セパレートだ、とわかったらはじいてもいいということだそうです。

さらにちなみに、フリーのリモセンソフトのMultiSpecで、バンド別の画像を合成してTIFFファイルを出力すると セパレートタイプとして出力されます。

以下のサンプルコードは、そのMultiSpecで合成されたセパレート8バンドのTIFFファイルから、 指定したバンド3つを合成してカラーの通常フォーマットのTIFFファイルに書き出すサンプルです。

#include "../../#libtiff/tiffio.h"

int main( int argc, char *argv[] )
{
    int i, j;
    int nImageWidth, nImageLength, nSample = 0, nBits = 0, nRows = 0, nPlan = 0;
    unsigned char *pbIn_R, *pbIn_G, *pbIn_B, *pbOut;

    TIFF *pTif = TIFFOpen( argv[1], "r" );
    if ( !pTif )
    {
        fprintf( stderr, "Unable to open TIFF file [%s]\n", argv[1] );
        exit( 1 );
    }

    TIFF *pOut = TIFFOpen( argv[2], "w" );
    if ( !pOut )
    {
        fprintf( stderr, "Unable to create TIFF file [%s]\n", argv[2] );
        TIFFClose( pTif );
        exit( 1 );
    }

    int nR = atoi( argv[3] );
    int nG = atoi( argv[4] );
    int nB = atoi( argv[5] );

    TIFFGetField( pTif, TIFFTAG_IMAGEWIDTH, &nImageWidth );
    TIFFGetField( pTif, TIFFTAG_IMAGELENGTH, &nImageLength );
    TIFFGetField( pTif, TIFFTAG_SAMPLESPERPIXEL, &nSample );
    TIFFGetField( pTif, TIFFTAG_BITSPERSAMPLE, &nBits );
    TIFFGetField( pTif, TIFFTAG_ROWSPERSTRIP, &nRows );
    TIFFGetField( pTif, TIFFTAG_PLANARCONFIG, &nPlan );    // nPlan==2ならセパレート

    if ( nBits != 8 )
    {
        fprintf( stderr, "File is no 8bit\n" );
        TIFFClose( pTif );
        TIFFClose( pOut );
        exit( 1 );
    }

    TIFFSetField( pOut, TIFFTAG_IMAGEWIDTH, nImageWidth );
    TIFFSetField( pOut, TIFFTAG_IMAGELENGTH, nImageLength );
    TIFFSetField( pOut, TIFFTAG_SAMPLESPERPIXEL, 3 );
    TIFFSetField( pOut, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB );
    TIFFSetField( pOut, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG );
    TIFFSetField( pOut, TIFFTAG_BITSPERSAMPLE, nBits );

    pbIn_R = (unsigned char *)_TIFFmalloc( TIFFScanlineSize( pTif ) );
    pbIn_G = (unsigned char *)_TIFFmalloc( TIFFScanlineSize( pTif ) );
    pbIn_B = (unsigned char *)_TIFFmalloc( TIFFScanlineSize( pTif ) );
    pbOut = (unsigned char *)_TIFFmalloc( TIFFScanlineSize( pTif ) * 3 );

    for ( i = 0; i < nImageLength; i++ )
    {
        TIFFReadScanline( pTif, pbIn_R, i, nR );
        TIFFReadScanline( pTif, pbIn_G, i, nG );
        TIFFReadScanline( pTif, pbIn_B, i, nB );
        for ( j = 0; j < nImageWidth; j++ )
        {
            pbOut[j*3+0] = pbIn_R[j];
            pbOut[j*3+1] = pbIn_G[j];
            pbOut[j*3+2] = pbIn_B[j];
        }
        TIFFWriteScanline( pOut, pbOut, i );
    }

    _TIFFfree( pbIn_R );
    _TIFFfree( pbIn_G );
    _TIFFfree( pbIn_B );
    _TIFFfree( pbOut );

    TIFFClose( pTif );
    TIFFClose( pOut );

    return 0;
}

参考文献


クリエイティブ・コモンズ・ライセンス
This documents by Yamate,N is licensed under a Creative Commons 表示 - 継承 3.0 非移植 License.
login