1 /*************************************************************************
3 * Source file for Windows 95/Win32.
5 * The function LoadTIFFinDIB in this source file let you load
6 * a TIFF file and build a memory DIB with it and return the
7 * HANDLE (HDIB) of the memory bloc containing the DIB.
12 * hDIB = LoadTIFFinDIB("sample.tif");
15 * To build this source file you must include the TIFF library
18 * 4/12/95 Philippe Tenenhaus 100423.3705@compuserve.com
20 ************************************************************************/
26 #define IS_WIN30_DIB(lpbi) ((*(LPDWORD)(lpbi)) == sizeof(BITMAPINFOHEADER))
27 #define CVT(x) (((x) * 255L) / ((1L<<16)-1))
29 static HDIB
CreateDIB(DWORD dwWidth
, DWORD dwHeight
, WORD wBitCount
);
30 static LPSTR
FindDIBBits(LPSTR lpDIB
);
31 static WORD
PaletteSize(LPSTR lpDIB
);
32 static WORD
DIBNumColors(LPSTR lpDIB
);
33 static int checkcmap(int n
, uint16
* r
, uint16
* g
, uint16
* b
);
37 /*************************************************************************
39 * HDIB LoadTIFFinDIB(LPSTR lpFileName)
43 * LPSTR lpDIB - File name of a tiff imag
47 * LPSTR - HANDLE of a DIB
51 * This function load a TIFF file and build a memory DIB with it
52 * and return the HANDLE (HDIB) of the memory bloc containing
55 * 4/12/95 Philippe Tenenhaus 100423.3705@compuserve.com
57 ************************************************************************/
59 HDIB
LoadTIFFinDIB(LPSTR lpFileName
)
62 unsigned long imageLength
;
63 unsigned long imageWidth
;
64 unsigned int BitsPerSample
;
65 unsigned long LineSize
;
66 unsigned int SamplePerPixel
;
67 unsigned long RowsPerStrip
;
68 int PhotometricInterpretation
;
72 LPBITMAPINFOHEADER lpDIB
;
79 tif
= TIFFOpen(lpFileName
, "r");
84 TIFFGetField(tif
, TIFFTAG_IMAGEWIDTH
, &imageWidth
);
85 TIFFGetField(tif
, TIFFTAG_IMAGELENGTH
, &imageLength
);
86 TIFFGetField(tif
, TIFFTAG_BITSPERSAMPLE
, &BitsPerSample
);
87 TIFFGetField(tif
, TIFFTAG_ROWSPERSTRIP
, &RowsPerStrip
);
88 TIFFGetField(tif
, TIFFTAG_ROWSPERSTRIP
, &RowsPerStrip
);
89 TIFFGetField(tif
, TIFFTAG_PHOTOMETRIC
, &PhotometricInterpretation
);
91 LineSize
= TIFFScanlineSize(tif
); //Number of byte in ine line
93 SamplePerPixel
= (int) (LineSize
/imageWidth
);
95 //Align = Number of byte to add at the end of each line of the DIB
96 Align
= 4 - (LineSize
% 4);
97 if (Align
== 4) Align
= 0;
101 hDIB
= CreateDIB((DWORD
) imageWidth
, (DWORD
) imageLength
, (WORD
)
102 (BitsPerSample
*SamplePerPixel
));
103 lpDIB
= (LPBITMAPINFOHEADER
) GlobalLock(hDIB
);
108 lpBits
= FindDIBBits((LPSTR
) lpDIB
);
110 //In the tiff file the lines are save from up to down
111 //In a DIB the lines must be save from down to up
114 lpBits
= FindDIBBits((LPSTR
) lpDIB
);
115 lpBits
+=((imageWidth
*SamplePerPixel
)+Align
)*(imageLength
-1);
116 //now lpBits pointe on the bottom line
118 hStrip
= GlobalAlloc(GHND
,TIFFStripSize(tif
));
119 buf
= GlobalLock(hStrip
);
124 //PhotometricInterpretation = 2 image is RGB
125 //PhotometricInterpretation = 3 image have a color palette
126 if (PhotometricInterpretation
== 3)
135 TIFFGetField(tif
, TIFFTAG_COLORMAP
, &red
, &green
, &blue
);
137 //Is the palette 16 or 8 bits ?
138 if (checkcmap(1<<BitsPerSample
, red
, green
, blue
) == 16)
139 Palette16Bits
= TRUE
;
141 Palette16Bits
= FALSE
;
143 lpbmi
= (LPBITMAPINFO
)lpDIB
;
145 //load the palette in the DIB
146 for (i
= (1<<BitsPerSample
)-1; i
>= 0; i
--)
150 lpbmi
->bmiColors
[i
].rgbRed
=(BYTE
) CVT(red
[i
]);
151 lpbmi
->bmiColors
[i
].rgbGreen
= (BYTE
) CVT(green
[i
]);
152 lpbmi
->bmiColors
[i
].rgbBlue
= (BYTE
) CVT(blue
[i
]);
156 lpbmi
->bmiColors
[i
].rgbRed
= (BYTE
) red
[i
];
157 lpbmi
->bmiColors
[i
].rgbGreen
= (BYTE
) green
[i
];
158 lpbmi
->bmiColors
[i
].rgbBlue
= (BYTE
) blue
[i
];
164 //read the tiff lines and save them in the DIB
165 //with RGB mode, we have to change the order of the 3 samples RGB
167 for (row
= 0; row
< imageLength
; row
+= RowsPerStrip
)
169 nrow
= (row
+ RowsPerStrip
> imageLength
? imageLength
- row
:
171 if (TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, row
, 0),
172 buf
, nrow
*LineSize
)==-1)
178 for (l
= 0; l
< nrow
; l
++)
180 if (SamplePerPixel
== 3)
181 for (i
=0;i
< (int) (imageWidth
);i
++)
183 lpBits
[i
*SamplePerPixel
+0]=buf
[l
*LineSize
+i
*Sample
185 lpBits
[i
*SamplePerPixel
+1]=buf
[l
*LineSize
+i
*Sample
187 lpBits
[i
*SamplePerPixel
+2]=buf
[l
*LineSize
+i
*Sample
191 memcpy(lpBits
, &buf
[(int) (l
*LineSize
)], (int)
192 imageWidth
*SamplePerPixel
);
194 lpBits
-=imageWidth
*SamplePerPixel
+Align
;
199 GlobalUnlock(hStrip
);
221 static int checkcmap(int n
, uint16
* r
, uint16
* g
, uint16
* b
)
224 if (*r
++ >= 256 || *g
++ >= 256 || *b
++ >= 256)
232 /*************************************************************************
233 * All the following functions were created by microsoft, they are
234 * parts of the sample project "wincap" given with the SDK Win32.
236 * Microsoft says that :
238 * You have a royalty-free right to use, modify, reproduce and
239 * distribute the Sample Files (and/or any modified version) in
240 * any way you find useful, provided that you agree that
241 * Microsoft has no warranty obligations or liability for any
242 * Sample Application Files which are modified.
244 ************************************************************************/
246 HDIB
CreateDIB(DWORD dwWidth
, DWORD dwHeight
, WORD wBitCount
)
248 BITMAPINFOHEADER bi
; // bitmap header
249 LPBITMAPINFOHEADER lpbi
; // pointer to BITMAPINFOHEADER
250 DWORD dwLen
; // size of memory block
252 DWORD dwBytesPerLine
; // Number of bytes per scanline
255 // Make sure bits per pixel is valid
258 else if (wBitCount
<= 4)
260 else if (wBitCount
<= 8)
262 else if (wBitCount
<= 24)
265 wBitCount
= 4; // set default value to 4 if parameter is bogus
267 // initialize BITMAPINFOHEADER
268 bi
.biSize
= sizeof(BITMAPINFOHEADER
);
269 bi
.biWidth
= dwWidth
; // fill in width from parameter
270 bi
.biHeight
= dwHeight
; // fill in height from parameter
271 bi
.biPlanes
= 1; // must be 1
272 bi
.biBitCount
= wBitCount
; // from parameter
273 bi
.biCompression
= BI_RGB
;
274 bi
.biSizeImage
= (dwWidth
*dwHeight
*wBitCount
)/8; //0; // 0's here
276 bi
.biXPelsPerMeter
= 2834; //0;
277 bi
.biYPelsPerMeter
= 2834; //0;
279 bi
.biClrImportant
= 0;
281 // calculate size of memory block required to store the DIB. This
282 // block should be big enough to hold the BITMAPINFOHEADER, the color
283 // table, and the bits
285 dwBytesPerLine
= (((wBitCount
* dwWidth
) + 31) / 32 * 4);
286 dwLen
= bi
.biSize
+ PaletteSize((LPSTR
)&bi
) + (dwBytesPerLine
* dwHeight
);
288 // alloc memory block to store our bitmap
289 hDIB
= GlobalAlloc(GHND
, dwLen
);
291 // major bummer if we couldn't get memory block
297 // lock memory and get pointer to it
298 lpbi
= (VOID FAR
*)GlobalLock(hDIB
);
300 // use our bitmap info structure to fill in first part of
301 // our DIB with the BITMAPINFOHEADER
304 // Since we don't know what the colortable and bits should contain,
305 // just leave these blank. Unlock the DIB and return the HDIB.
309 /* return handle to the DIB */
314 LPSTR FAR
FindDIBBits(LPSTR lpDIB
)
316 return (lpDIB
+ *(LPDWORD
)lpDIB
+ PaletteSize(lpDIB
));
320 WORD FAR
PaletteSize(LPSTR lpDIB
)
322 /* calculate the size required by the palette */
323 if (IS_WIN30_DIB (lpDIB
))
324 return (DIBNumColors(lpDIB
) * sizeof(RGBQUAD
));
326 return (DIBNumColors(lpDIB
) * sizeof(RGBTRIPLE
));
330 WORD
DIBNumColors(LPSTR lpDIB
)
332 WORD wBitCount
; // DIB bit count
334 /* If this is a Windows-style DIB, the number of colors in the
335 * color table can be less than the number of bits per pixel
336 * allows for (i.e. lpbi->biClrUsed can be set to some value).
337 * If this is the case, return the appropriate value.
340 if (IS_WIN30_DIB(lpDIB
))
344 dwClrUsed
= ((LPBITMAPINFOHEADER
)lpDIB
)->biClrUsed
;
346 return (WORD
)dwClrUsed
;
349 /* Calculate the number of colors in the color table based on
350 * the number of bits per pixel for the DIB.
352 if (IS_WIN30_DIB(lpDIB
))
353 wBitCount
= ((LPBITMAPINFOHEADER
)lpDIB
)->biBitCount
;
355 wBitCount
= ((LPBITMAPCOREHEADER
)lpDIB
)->bcBitCount
;
357 /* return number of colors based on bits per pixel */