7 #include <stdlib.h> // MAX_ constants
10 /*--------------------------------------------------------------------
12 Load the TIFF data from the file into memory. Return
13 a pointer to a valid DIB (or NULL for errors).
14 Uses the TIFFRGBA interface to libtiff.lib to convert
15 most file formats to a useable form. We just keep the 32 bit
16 form of the data to display, rather than optimizing for the
21 int ChkTIFF ( LPCTSTR lpszPath )
22 PVOID ReadTIFF ( LPCTSTR lpszPath )
25 A valid DIB pointer for success; NULL for failure.
27 --------------------------------------------------------------------*/
29 #include "TiffLib/tiff.h"
30 #include "TiffLib/tiffio.h"
35 // piggyback some data on top of the RGBA Image
42 HANDLE LoadTIFFinDIB(LPCTSTR lpFileName);
43 HANDLE TIFFRGBA2DIB(TIFFDibImage* dib, uint32* raster) ;
46 MyWarningHandler(const char* module, const char* fmt, va_list ap)
48 // ignore all warnings (unused tags, etc)
53 MyErrorHandler(const char* module, const char* fmt, va_list ap)
58 // Turn off the error and warning handlers to check if a valid file.
59 // Necessary because of the way that the Doc loads images and restart files.
60 int ChkTIFF ( LPCTSTR lpszPath )
67 eh = TIFFSetErrorHandler(NULL);
68 wh = TIFFSetWarningHandler(NULL);
70 TIFF* tif = TIFFOpen(lpszPath, "r");
76 TIFFSetErrorHandler(eh);
77 TIFFSetWarningHandler(wh);
82 void DibInstallHack(TIFFDibImage* img) ;
84 PVOID ReadTIFF ( LPCTSTR lpszPath )
89 wh = TIFFSetWarningHandler(MyWarningHandler);
91 if (ChkTIFF(lpszPath)) {
92 TIFF* tif = TIFFOpen(lpszPath, "r");
96 if (TIFFRGBAImageOK(tif, emsg)) {
100 if (TIFFRGBAImageBegin(&img.tif, tif, -1, emsg)) {
104 DibInstallHack(&img);
106 npixels = img.tif.width * img.tif.height;
107 raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));
108 if (raster != NULL) {
109 if (TIFFRGBAImageGet(&img.tif, raster, img.tif.width, img.tif.height)) {
110 pDIB = TIFFRGBA2DIB(&img, raster);
115 TIFFRGBAImageEnd(&img.tif);
118 TRACE("Unable to open image(%s): %s\n", lpszPath, emsg );
124 TIFFSetWarningHandler(wh);
131 HANDLE TIFFRGBA2DIB(TIFFDibImage* dib, uint32* raster)
134 TIFFRGBAImage* img = &dib->tif;
138 uint16 BitsPerSample;
139 uint16 SamplePerPixel;
141 uint16 PhotometricInterpretation;
146 TIFFGetField(img->tif, TIFFTAG_IMAGEWIDTH, &imageWidth);
147 TIFFGetField(img->tif, TIFFTAG_IMAGELENGTH, &imageLength);
148 TIFFGetField(img->tif, TIFFTAG_BITSPERSAMPLE, &BitsPerSample);
149 TIFFGetField(img->tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip);
150 TIFFGetField(img->tif, TIFFTAG_SAMPLESPERPIXEL, &SamplePerPixel);
151 TIFFGetField(img->tif, TIFFTAG_PHOTOMETRIC, &PhotometricInterpretation);
153 if ( BitsPerSample == 1 && SamplePerPixel == 1 && dib->dibinstalled ) { // bilevel
154 bi.biSize = sizeof(BITMAPINFOHEADER);
155 bi.biWidth = imageWidth;
156 bi.biHeight = imageLength;
157 bi.biPlanes = 1; // always
159 bi.biCompression = BI_RGB;
160 bi.biSizeImage = WIDTHBYTES(bi.biWidth * bi.biBitCount) * bi.biHeight;
161 bi.biXPelsPerMeter = 0;
162 bi.biYPelsPerMeter = 0;
163 bi.biClrUsed = 0; // must be zero for RGB compression (none)
164 bi.biClrImportant = 0; // always
166 // Get the size of the DIB
167 dwDIBSize = GetDIBSize( &bi );
169 // Allocate for the BITMAPINFO structure and the color table.
170 pDIB = GlobalAllocPtr( GHND, dwDIBSize );
175 // Copy the header info
176 *((BITMAPINFOHEADER*)pDIB) = bi;
178 // Get a pointer to the color table
179 RGBQUAD *pRgbq = (RGBQUAD *)((LPSTR)pDIB + sizeof(BITMAPINFOHEADER));
182 pRgbq[0].rgbBlue = 0;
183 pRgbq[0].rgbGreen = 0;
184 pRgbq[0].rgbReserved = 0;
185 pRgbq[1].rgbRed = 255;
186 pRgbq[1].rgbBlue = 255;
187 pRgbq[1].rgbGreen = 255;
188 pRgbq[1].rgbReserved = 255;
190 // Pointers to the bits
191 //PVOID pbiBits = (LPSTR)pRgbq + bi.biClrUsed * sizeof(RGBQUAD);
193 // In the BITMAPINFOHEADER documentation, it appears that
194 // there should be no color table for 32 bit images, but
195 // experience shows that the image is off by 3 words if it
196 // is not included. So here it is.
197 PVOID pbiBits = GetDIBImagePtr((BITMAPINFOHEADER*)pDIB); //(LPSTR)pRgbq + 3 * sizeof(RGBQUAD);
199 int sizeWords = bi.biSizeImage/4;
200 RGBQUAD* rgbDib = (RGBQUAD*)pbiBits;
201 long* rgbTif = (long*)raster;
203 _TIFFmemcpy(pbiBits, raster, bi.biSizeImage);
206 // For now just always default to the RGB 32 bit form. // save as 32 bit for simplicity
207 else if ( true /*BitsPerSample == 8 && SamplePerPixel == 3*/ ) { // 24 bit color
209 bi.biSize = sizeof(BITMAPINFOHEADER);
210 bi.biWidth = imageWidth;
211 bi.biHeight = imageLength;
212 bi.biPlanes = 1; // always
214 bi.biCompression = BI_RGB;
215 bi.biSizeImage = WIDTHBYTES(bi.biWidth * bi.biBitCount) * bi.biHeight;
216 bi.biXPelsPerMeter = 0;
217 bi.biYPelsPerMeter = 0;
218 bi.biClrUsed = 0; // must be zero for RGB compression (none)
219 bi.biClrImportant = 0; // always
221 // Get the size of the DIB
222 dwDIBSize = GetDIBSize( &bi );
224 // Allocate for the BITMAPINFO structure and the color table.
225 pDIB = GlobalAllocPtr( GHND, dwDIBSize );
230 // Copy the header info
231 *((BITMAPINFOHEADER*)pDIB) = bi;
233 // Get a pointer to the color table
234 RGBQUAD *pRgbq = (RGBQUAD *)((LPSTR)pDIB + sizeof(BITMAPINFOHEADER));
236 // Pointers to the bits
237 //PVOID pbiBits = (LPSTR)pRgbq + bi.biClrUsed * sizeof(RGBQUAD);
239 // In the BITMAPINFOHEADER documentation, it appears that
240 // there should be no color table for 32 bit images, but
241 // experience shows that the image is off by 3 words if it
242 // is not included. So here it is.
243 PVOID pbiBits = (LPSTR)pRgbq + 3 * sizeof(RGBQUAD);
245 int sizeWords = bi.biSizeImage/4;
246 RGBQUAD* rgbDib = (RGBQUAD*)pbiBits;
247 long* rgbTif = (long*)raster;
249 // Swap the byte order while copying
250 for ( int i = 0 ; i < sizeWords ; ++i )
252 rgbDib[i].rgbRed = TIFFGetR(rgbTif[i]);
253 rgbDib[i].rgbBlue = TIFFGetB(rgbTif[i]);
254 rgbDib[i].rgbGreen = TIFFGetG(rgbTif[i]);
255 rgbDib[i].rgbReserved = 0;
265 ///////////////////////////////////////////////////////////////
267 // Hacked from tif_getimage.c in libtiff in v3.5.7
270 typedef unsigned char u_char;
273 #define DECLAREContigPutFunc(name) \
275 TIFFRGBAImage* img, \
277 uint32 x, uint32 y, \
278 uint32 w, uint32 h, \
279 int32 fromskew, int32 toskew, \
283 #define DECLARESepPutFunc(name) \
287 uint32 x, uint32 y, \
289 int32 fromskew, int32 toskew,\
290 u_char* r, u_char* g, u_char* b, u_char* a\
293 DECLAREContigPutFunc(putContig1bitTile);
294 static int getStripContig1Bit(TIFFRGBAImage* img, uint32* uraster, uint32 w, uint32 h);
296 //typdef struct TIFFDibImage {
297 // TIFFRGBAImage tif;
301 void DibInstallHack(TIFFDibImage* dib) {
302 TIFFRGBAImage* img = &dib->tif;
303 dib->dibinstalled = false;
304 switch (img->photometric) {
305 case PHOTOMETRIC_MINISWHITE:
306 case PHOTOMETRIC_MINISBLACK:
307 switch (img->bitspersample) {
309 img->put.contig = putContig1bitTile;
310 img->get = getStripContig1Bit;
311 dib->dibinstalled = true;
319 * 1-bit packed samples => 1-bit
321 * Override to just copy the data
323 DECLAREContigPutFunc(putContig1bitTile)
325 int samplesperpixel = img->samplesperpixel;
328 fromskew *= samplesperpixel;
329 int wb = WIDTHBYTES(w);
330 u_char* ucp = (u_char*)cp;
332 /* Conver 'w' to bytes from pixels (rounded up) */
336 _TIFFmemcpy(ucp, pp, w);
338 for (x = wb; x-- > 0;) {
339 *cp++ = rgbi(Map[pp[0]], Map[pp[1]], Map[pp[2]]);
340 pp += samplesperpixel;
343 ucp += (wb + toskew);
344 pp += (w + fromskew);
349 * Hacked from the tif_getimage.c file.
352 setorientation(TIFFRGBAImage* img, uint32 h)
354 TIFF* tif = img->tif;
357 switch (img->orientation) {
358 case ORIENTATION_BOTRIGHT:
359 case ORIENTATION_RIGHTBOT: /* XXX */
360 case ORIENTATION_LEFTBOT: /* XXX */
361 TIFFWarning(TIFFFileName(tif), "using bottom-left orientation");
362 img->orientation = ORIENTATION_BOTLEFT;
364 case ORIENTATION_BOTLEFT:
367 case ORIENTATION_TOPRIGHT:
368 case ORIENTATION_RIGHTTOP: /* XXX */
369 case ORIENTATION_LEFTTOP: /* XXX */
371 TIFFWarning(TIFFFileName(tif), "using top-left orientation");
372 img->orientation = ORIENTATION_TOPLEFT;
374 case ORIENTATION_TOPLEFT:
382 * Get a strip-organized image that has
383 * PlanarConfiguration contiguous if SamplesPerPixel > 1
385 * SamplesPerPixel == 1
387 * Hacked from the tif_getimage.c file.
389 * This is set up to allow us to just copy the data to the raster
393 getStripContig1Bit(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
395 TIFF* tif = img->tif;
396 tileContigRoutine put = img->put.contig;
398 uint32 row, y, nrow, rowstoread;
402 uint32 imagewidth = img->width;
404 int32 fromskew, toskew;
407 u_char* braster = (u_char*)raster; // byte wide raster
408 uint32 wb = WIDTHBYTES(w);
411 buf = (u_char*) _TIFFmalloc(TIFFStripSize(tif));
413 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for strip buffer");
416 y = setorientation(img, h);
417 orientation = img->orientation;
418 toskew = -(int32) (orientation == ORIENTATION_TOPLEFT ? wb+wb : wb-wb);
419 TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
420 scanline = TIFFScanlineSize(tif);
421 fromskew = (w < imagewidth ? imagewidth - w : 0)/8;
422 for (row = 0; row < h; row += nrow)
424 rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
425 nrow = (row + rowstoread > h ? h - row : rowstoread);
426 strip = TIFFComputeStrip(tif,row+img->row_offset, 0);
427 stripsize = ((row + img->row_offset)%rowsperstrip + nrow) * scanline;
428 if (TIFFReadEncodedStrip(tif, strip, buf, stripsize ) < 0
435 pos = ((row + img->row_offset) % rowsperstrip) * scanline;
436 (*put)(img, (uint32*)(braster+y*wb), 0, y, w, nrow, fromskew, toskew, buf + pos);
437 y += (orientation == ORIENTATION_TOPLEFT ?-(int32) nrow : (int32) nrow);