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 */