A TGraphic Descendant for TIFFs

Handling TIFFs under Borland C++ Builder 6 using Libtiff

Purpose of Project

I set out to create an object that could load and save TIFF files and could be used with VCL (and easily converted to CLX) under Borland C++ Builder V. 6. This graphics object would descend from TGraphic, and could be registered with the TPicture class so as to be usable easily with various VCL graphic components. In addition, I wanted to use the component with data aware controls in order to save and load pictures in connection with databases.

I needed to be able to read and write TIFF files using streams, so they could be written to file, memory or to blobs. When I first started the project I was planning to modify libtiff in to change its file io routines, but as it turns out, this well designed library makes the process easy. One merely has to skip the standard _TIFFOpen and _TIFFFdOpen functions, contained in the implementation specific file (for Windows users, tif_win32.c) and instead directly call _TIFFClientOpen, passing your own i/o routines to the library. There is a fine set of templates in the same file, and the modifications are minimal (see tiffclass.cpp).

I spent a bit more time with the conversion of TIFF files to bitmaps which was how I wanted to work with them in memory. Those with more difficult requirements than I have, or those with a bit more facility directly manipulating bitmaps may want to improve on these functions, but mine do work.

The one decision I think may be doubtful was converting all TIFFs with 8 bits per pixel to 24 bit RGB images. I really hate dealing with palettes and stored images, and I have a long history of bad luck writing good, consistently working code. Since the color integrity was important to me, and the memory wasn't, I chose to convert. The routine I'm using right now to do the conversion is inefficient, but I have very few such images to work with, and all of those are small, so the overhead doesn't get too bad. Directly copying the altered data into the bitmap's buffer would be more efficient.

I believe that the tiffclass code is fairly straightforward with the comments I have put in the files, so I've made them available for viewing as tiffclassh.html (tiffclass.h) and tiffclasscpp.html (tiffclass.cpp). You can look to see whether this code will do you any good before you download any of the zip files. All the source and project files are available in the zip files listed at the end of this document.

There is a difference between a file stream and a Blob stream which had to be handled. If you seek past the end of a file in a file stream in write mode, the file is expanded. In a blob stream, the Seek works, but the next write will fail with an error. I simply write a block of memory to the blob to fill the space.

One last thing about tiffclass: It will work with the current version of libtiff, compiled for Windows (such as at GnuWin32), but in working with it I created a project file to build the library under Borland C++ Builder V.6. I'm not sure if there's an easier way, but I found it necessary to add __declspec(dllexport) to the exported functions in tiffio.h and tiffiop.h. I've zipped the modified files and the project file as libtiff-add.zip. This is not a necessary element of creating tiffclass. If you use libtiff3.dll, use the "-a" switch on implib, because you will need the C style underscores.

eneTIFFBitmap

The component itself is embarassingly trivial once tiffclass is available. I made my object a descendant of TBitmap which is in turn descended form TGraphic (which is the key). I had written one of my own that was much more complicated, and also worked, but it simply did much of TBitmap's work again, so I abandoned it. This one adds just a TIFFFile class, and two public member functions, LoadFromStream and SaveToStream, which will be called by TPicture to load the file.

You then have to register the new class with TPicture somewhere in the creation of whatever form you're using, probably under the OnCreate method. I do this in the demonstration program, tifftest.exe. You can preview the source code here: displaycpp.html (Display.cpp). There's nothing at all interesting in the display.h file, so I haven't made a separate view of it. Both are included in the ZIP listed below, of course.

Deployment Notes

I haven't posted any full BCB6 projects before, so if you have problems with any of this, just e-mail me at ncs@hneufeld.com and I'll try to correct it. I included the compiled versions of everything, but none of the Borland redistributables, because this program is intended for Builder users, and I don't see how anyone else will benefit. If you have builder, you have all the files.

Links to project files:

Project file and modified tiffio.h/tiffiop.h files for building libtiff with BCB6

Project group, project files and all support for the eneTIFFBitmap object

LIBTIFF Home Page

Home The Goal Gurus Consulting Services Software Development Henry Neufeld's Resume Suggested Links Email NCS