Tag Image File Format (TIFF) files are used for a diverse set of applications such as GIS (geographic information systems), CAD drawing programs, etc... Fortunately for programmers like us, a portable and easy to use library is freely available, from www.libtiff.org, for decoding the information stored in TIFF files.
This article outlines and provides an implementation of a simple approach that will allow you to include support for TIFF files in your applications with a few library calls.
Here is an outline of the approach:
Use the "TIFFOpen" call passing in a filename and io mode.
Use the "TIFFGetField" function to read the image height and width tags, then allocate the required space (WxHx4).
Use "TIFFReadRGBAImage" to copy the actual pixel data from the file to the space you just allocated.
Copy the raster data to a Device Independent Bitmap (DIB) using care to maintain the picture layout.
Delete the allocated space for the pixel data.
Call "TIFFClose" to free resources allocated in the library.
Draw the DIB to the screen.
The following code sample implements the approach outlined above:
// 1) Open this puppy up
TIFF * tiff = TIFFOpen((char*)(LPCTSTR)m_filename,"r");
if (tiff)
{
int w=0, h=0;
// 2)
// Get the width and height of the image
TIFFGetField(tiff,TIFFTAG_IMAGEWIDTH, &w);
TIFFGetField(tiff,TIFFTAG_IMAGELENGTH, &h);
if ((w > 0) && (h > 0))
{
// allocate space for the image
uint32 * raster =
(uint32*)GlobalAlloc(GMEM_FIXED,
(w * h * sizeof (uint32)));
if (raster)
{
// creating DIBSection object that encapsulates
// DIB functionality
if (m_dib)
delete m_dib;
m_dib = new DIBSection;
if (m_dib)
{
m_dib->Create(w,h,32);
uint32 dibwidth = m_dib->GetTotalWidth();
// 3)
// copy all the pixel data from the file into
// allocated space
if (TIFFReadRGBAImage(tiff, w, h, raster, 0))
{
// 4)
// its tempting to copy straight to the DIB,
// however the DIB has an alignment
// restriction that is not applicable to
// tiff files...so they may have different
// widths
unsigned long * dest =
(unsigned long *)m_dib->GetBits();
// 5)
// free the temporary pixel storage space
GlobalFree(raster);
}
}
// 6)
// notify the TIFF library that we are done
// with this puppy
TIFFClose(tiff);
}
}
}
void TIFFTestView::OnDraw(CDC* pDC)
{
TIFFTestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
DIBSection * dib = pDoc->GetDIB();
if (pDC->IsPrinting())
{}
else
{
if (dib)
{
CClientDC dc(this);
CPoint sp = GetScrollPosition();
dib->Draw(&dc,sp.x,sp.y);
}
}
}
Additional information about the sample project:
The sample project includes debug and release versions of the TIFF library files that I built, plus header files for the library. This is the minimum required to build the sample project. If you have an interest in working with TIFF files on an ongoing basis I highly recommend that you download the source files and build environment from www.libtiff.org and go through the library build process...it can be painful, but worthwhile in terms of understanding the library.
In 256 color mode the colors may not be correct, but in 16-bit, 24-bit, and 32-bit color mode everything looks fine.