TIFFファイルの読み方などはlibtiffのチュートリアルにあるとおりですが、
まとめてみました。
最低限読み込んでおきたいタグ
TIFFのタグはたくさんの種類がありますが、必須のものはいくつかです。
大体以下のタグを読み込んでおけば何とかなります。
- TIFFTAG_IMAGEWIDTH、およびTIFFTAG_IMAGELENGTH
- 画像の縦横サイズ
- TIFFTAG_SAMPLESPERPIXEL
- ピクセルあたりの色数
- TIFFTAG_BITSPERSAMPLE
- ピクセルの色深度(ビット数)
- TIFFTAG_PHOTOMETRIC
- 正確な表現かどうかわかりませんが、画像の種別
- TIFFTAG_PLANARCONFIG
- このタグの数値が1(CONTIG)ならばBIP配列、2(SEPARATE)ならBIL配列
TIFFTAG_PHOTOMETRIC
は、タグの数値によって以下のように定義されています。
以下の表は一般的なものをピックアップしました。
そのほかのものはよくわかりません(見たこともありません)。
0 | モノクロ2階調(※) |
1 | グレースケール |
2 | RGBカラー |
3 | インデックスカラー |
6 | YCbCrカラー、JPEG圧縮ならこうなる |
※
POHOTOMETRICが0は、min-is-whiteなので、libtiffの定義と違うように思われますが、
この値で代用しているのかもしれません。
このほか、タイル配列の場合はTIFFTAG_TILEWIDTH
、TIFFTAG_TILELENGTH
を読み込む必要があります。
タイル配列の読み込みはJPEG/TILEのTIFF読み込み方法を参照してください。
また、念のため読んでおきたいタグとして以下のものが挙げられると思います。
- TIFFTAG_ROWSPERSTRIP
- 数行をひとまとめにして1ストリップと定義している場合
- TIFFTAG_ORIENTATION
- 普通はORIENTATION_TOPLEFTだが、まれに別の場所が画像原点として定義されており、この場合は表示のときに画像を回転する必要がある
8bit、RGBまたはグレースケールの場合の読み込み
例として、8bitのRGBもしくはグレースケール画像、スキャンライン配列、CONTIG配列の読み込みを以下に示します
(多分大丈夫だと思います)。
エラー処理などは省略しているところがあります。
bool ReadTIFF( LPCTSTR lpszFName ) { int nImageLength; int nImageWidth; int nBitsPerSample; int nSamplePerPixel; int nPhotometric; int nRowsPerStrip; int i; int nRow; TIFF *pTif; LPBYTE pBuf; pTif = TIFFOpen( lpszFName, "r" ); if (!pTif) return false; if ( TIFFGetField( pTif, TIFFTAG_IMAGEWIDTH, &nImageWidth ) != 1 ) return false; if ( TIFFGetField( pTif, TIFFTAG_IMAGELENGTH, &nImageLength ) != 1 ) return false; if ( TIFFGetField( pTif, TIFFTAG_BITSPERSAMPLE, &nBitsPerSample ) != 1 ) return false; if ( TIFFGetField( pTif, TIFFTAG_SAMPLESPERPIXEL, &nSamplePerPixel ) != 1 ) return false; //ストリップ1つあたりの行数 エラーの場合はデフォルト値 if ( TIFFGetField( pTif, TIFFTAG_ROWSPERSTRIP, &nRowsPerStrip ) != 1 ) nRowsPerStrip = 1; if ( TIFFGetField( pTif, TIFFTAG_PHOTOMETRIC, &nPhotometric ) != 1 ) return false; pBuf = new BYTE[nImageWidth*nSamplePerPixel*nRowsPerStrip]; for ( i = 0; i < nImageLength; i += nRowsPerStrip ) { /* ストリップの行数を計算 */ nRow = (i + nRowsPerStrip > nImageLength) ? nImageLength - i : nRowsPerStrip; /* バッファに1ストリップ分読み込み */ if ( TIFFReadEncodedStrip( pTif, TIFFComputeStrip( pTif, i, 0 ), pBuf, nRow*nImageWidth*nSamplePerPixel ) == -1 ) { fprintf( stderr, "errorn" ); delete[] pBuf; return false; } else { /* バッファに入っているピクセルに対する処理 */ } } delete[] pBuf; TIFFClose( pTif ); return true; }
インデックスカラー、モノクロ2階調、16bit画像の場合はもう一工夫が必要です。