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
);