libtiff: 16bitのTIFFファイルの読み込み

画像データを受け取る配列をBYTEからWORDにする以外は
8bit画像の場合と同じですが、
注意点としてはlibtiffが公開しているサイズ計算関数のTIFFScanlineSize
TIFFStripSizeを使う場合、これらはバイト数を返すので
new[]演算子でWORD配列を確保したりすると倍のサイズのメモリを確保してしまいます。
_TIFFmalloc()関数を使うときはサイズ計算関数を使ったほうが便利です。

一応以下のコードで読めると思います。
この例ではTIFFStripSize()TIFFScanlineSize()を使い、
メモリ確保にGlobalAlloc()を使ってみました。

#include <windows.h>
#include <tiffio.h>

bool ReadTIFF( LPCTSTR lpszFName )
{
  UINT nRow;
  UINT row;
  WORD *buf;
  HGLOBAL hStrip;
  UINT l, i;
  WORD *data, *ptr;
  int nImageLength;
  int nImageWidth;
  int nBitsPerSample;
  int nSamplePerPixel;
  int nPhotometric;
  int nRowsPerStrip;
  TIFF *pTif;

  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;
  if ( TIFFGetField( pTif, TIFFTAG_ROWSPERSTRIP,     &nRowsPerStrip   ) != 1 )
    nRowsPerStrip = 1;
  if ( TIFFGetField( pTif, TIFFTAG_PHOTOMETRIC,      &nPhotometric    ) != 1 )
    return false;

  hStrip = GlobalAlloc(GHND,TIFFStripSize( pTif ) );
  
  if (!hStrip)
  {
    return false;
  }
  
  buf = (WORD *)GlobalLock(hStrip);

  for (row = 0; row < nImageLength; row += nRowsPerStrip )
  {
    nRow = (row + nRowsPerStrip > nImageLength ? nImageLength - row : nRowsPerStrip);
    if (
        TIFFReadEncodedStrip(pTif, TIFFComputeStrip(pTif, row, 0),
           buf, nRow*TIFFScanlineSize( pTif ) )==-1 )
    {
      GlobalUnlock( hStrip );
      GlobalFree( hStrip );
      return false;
    }
        else
    {
      /* バッファに入っているピクセルに対する処理 */
    }
  }
  
  GlobalUnlock(hStrip);
  GlobalFree(hStrip);
  TIFFClose( pTif );

  return true;
}
アーカイブ