diff options
Diffstat (limited to 'tiff/contrib/win_dib/tiff2dib.c')
-rwxr-xr-x | tiff/contrib/win_dib/tiff2dib.c | 379 |
1 files changed, 379 insertions, 0 deletions
diff --git a/tiff/contrib/win_dib/tiff2dib.c b/tiff/contrib/win_dib/tiff2dib.c new file mode 100755 index 0000000..475ef30 --- /dev/null +++ b/tiff/contrib/win_dib/tiff2dib.c @@ -0,0 +1,379 @@ +/************************************************************************* + * + * Source file for Windows 95/Win32. + * + * The function LoadTIFFinDIB in this source file let you load + * a TIFF file and build a memory DIB with it and return the + * HANDLE (HDIB) of the memory bloc containing the DIB. + * + * Example : + * + * HDIB hDIB; + * hDIB = LoadTIFFinDIB("sample.tif"); + * + * + * To build this source file you must include the TIFF library + * in your project. + * + * 4/12/95 Philippe Tenenhaus 100423.3705@compuserve.com + * + ************************************************************************/ + + +#include "tiffio.h" + +#define HDIB HANDLE +#define IS_WIN30_DIB(lpbi) ((*(LPDWORD)(lpbi)) == sizeof(BITMAPINFOHEADER)) +#define CVT(x) (((x) * 255L) / ((1L<<16)-1)) + +static HDIB CreateDIB(DWORD dwWidth, DWORD dwHeight, WORD wBitCount); +static LPSTR FindDIBBits(LPSTR lpDIB); +static WORD PaletteSize(LPSTR lpDIB); +static WORD DIBNumColors(LPSTR lpDIB); +static int checkcmap(int n, uint16* r, uint16* g, uint16* b); + + + +/************************************************************************* + * + * HDIB LoadTIFFinDIB(LPSTR lpFileName) + * + * Parameter: + * + * LPSTR lpDIB - File name of a tiff imag + * + * Return Value: + * + * LPSTR - HANDLE of a DIB + * + * Description: + * + * This function load a TIFF file and build a memory DIB with it + * and return the HANDLE (HDIB) of the memory bloc containing + * the DIB. + * + * 4/12/95 Philippe Tenenhaus 100423.3705@compuserve.com + * + ************************************************************************/ + +HDIB LoadTIFFinDIB(LPSTR lpFileName) +{ + TIFF *tif; + unsigned long imageLength; + unsigned long imageWidth; + unsigned int BitsPerSample; + unsigned long LineSize; + unsigned int SamplePerPixel; + unsigned long RowsPerStrip; + int PhotometricInterpretation; + long nrow; + unsigned long row; + char *buf; + LPBITMAPINFOHEADER lpDIB; + HDIB hDIB; + char *lpBits; + HGLOBAL hStrip; + int i,l; + int Align; + + tif = TIFFOpen(lpFileName, "r"); + + if (!tif) + goto TiffOpenError; + + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imageWidth); + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imageLength); + TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &BitsPerSample); + TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip); + TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip); + TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &PhotometricInterpretation); + + LineSize = TIFFScanlineSize(tif); //Number of byte in ine line + + SamplePerPixel = (int) (LineSize/imageWidth); + + //Align = Number of byte to add at the end of each line of the DIB + Align = 4 - (LineSize % 4); + if (Align == 4) Align = 0; + + + //Create a new DIB + hDIB = CreateDIB((DWORD) imageWidth, (DWORD) imageLength, (WORD) +(BitsPerSample*SamplePerPixel)); + lpDIB = (LPBITMAPINFOHEADER) GlobalLock(hDIB); + if (!lpDIB) + goto OutOfDIBMemory; + + if (lpDIB) + lpBits = FindDIBBits((LPSTR) lpDIB); + + //In the tiff file the lines are save from up to down + //In a DIB the lines must be save from down to up + if (lpBits) + { + lpBits = FindDIBBits((LPSTR) lpDIB); + lpBits+=((imageWidth*SamplePerPixel)+Align)*(imageLength-1); + //now lpBits pointe on the bottom line + + hStrip = GlobalAlloc(GHND,TIFFStripSize(tif)); + buf = GlobalLock(hStrip); + + if (!buf) + goto OutOfBufMemory; + + //PhotometricInterpretation = 2 image is RGB + //PhotometricInterpretation = 3 image have a color palette + if (PhotometricInterpretation == 3) + { + uint16* red; + uint16* green; + uint16* blue; + int16 i; + LPBITMAPINFO lpbmi; + int Palette16Bits; + + TIFFGetField(tif, TIFFTAG_COLORMAP, &red, &green, &blue); + + //Is the palette 16 or 8 bits ? + if (checkcmap(1<<BitsPerSample, red, green, blue) == 16) + Palette16Bits = TRUE; + else + Palette16Bits = FALSE; + + lpbmi = (LPBITMAPINFO)lpDIB; + + //load the palette in the DIB + for (i = (1<<BitsPerSample)-1; i >= 0; i--) + { + if (Palette16Bits) + { + lpbmi->bmiColors[i].rgbRed =(BYTE) CVT(red[i]); + lpbmi->bmiColors[i].rgbGreen = (BYTE) CVT(green[i]); + lpbmi->bmiColors[i].rgbBlue = (BYTE) CVT(blue[i]); + } + else + { + lpbmi->bmiColors[i].rgbRed = (BYTE) red[i]; + lpbmi->bmiColors[i].rgbGreen = (BYTE) green[i]; + lpbmi->bmiColors[i].rgbBlue = (BYTE) blue[i]; + } + } + + } + + //read the tiff lines and save them in the DIB + //with RGB mode, we have to change the order of the 3 samples RGB +<=> BGR + for (row = 0; row < imageLength; row += RowsPerStrip) + { + nrow = (row + RowsPerStrip > imageLength ? imageLength - row : +RowsPerStrip); + if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0), + buf, nrow*LineSize)==-1) + { + goto TiffReadError; + } + else + { + for (l = 0; l < nrow; l++) + { + if (SamplePerPixel == 3) + for (i=0;i< (int) (imageWidth);i++) + { + lpBits[i*SamplePerPixel+0]=buf[l*LineSize+i*Sample +PerPixel+2]; + lpBits[i*SamplePerPixel+1]=buf[l*LineSize+i*Sample +PerPixel+1]; + lpBits[i*SamplePerPixel+2]=buf[l*LineSize+i*Sample +PerPixel+0]; + } + else + memcpy(lpBits, &buf[(int) (l*LineSize)], (int) +imageWidth*SamplePerPixel); + + lpBits-=imageWidth*SamplePerPixel+Align; + + } + } + } + GlobalUnlock(hStrip); + GlobalFree(hStrip); + GlobalUnlock(hDIB); + TIFFClose(tif); + } + + return hDIB; + + OutOfBufMemory: + + TiffReadError: + GlobalUnlock(hDIB); + GlobalFree(hStrip); + OutOfDIBMemory: + TIFFClose(tif); + TiffOpenError: + return (HANDLE) 0; + + +} + + +static int checkcmap(int n, uint16* r, uint16* g, uint16* b) +{ + while (n-- > 0) + if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256) + return (16); + + return (8); +} + + + +/************************************************************************* + * All the following functions were created by microsoft, they are + * parts of the sample project "wincap" given with the SDK Win32. + * + * Microsoft says that : + * + * You have a royalty-free right to use, modify, reproduce and + * distribute the Sample Files (and/or any modified version) in + * any way you find useful, provided that you agree that + * Microsoft has no warranty obligations or liability for any + * Sample Application Files which are modified. + * + ************************************************************************/ + +HDIB CreateDIB(DWORD dwWidth, DWORD dwHeight, WORD wBitCount) +{ + BITMAPINFOHEADER bi; // bitmap header + LPBITMAPINFOHEADER lpbi; // pointer to BITMAPINFOHEADER + DWORD dwLen; // size of memory block + HDIB hDIB; + DWORD dwBytesPerLine; // Number of bytes per scanline + + + // Make sure bits per pixel is valid + if (wBitCount <= 1) + wBitCount = 1; + else if (wBitCount <= 4) + wBitCount = 4; + else if (wBitCount <= 8) + wBitCount = 8; + else if (wBitCount <= 24) + wBitCount = 24; + else + wBitCount = 4; // set default value to 4 if parameter is bogus + + // initialize BITMAPINFOHEADER + bi.biSize = sizeof(BITMAPINFOHEADER); + bi.biWidth = dwWidth; // fill in width from parameter + bi.biHeight = dwHeight; // fill in height from parameter + bi.biPlanes = 1; // must be 1 + bi.biBitCount = wBitCount; // from parameter + bi.biCompression = BI_RGB; + bi.biSizeImage = (dwWidth*dwHeight*wBitCount)/8; //0; // 0's here +mean "default" + bi.biXPelsPerMeter = 2834; //0; + bi.biYPelsPerMeter = 2834; //0; + bi.biClrUsed = 0; + bi.biClrImportant = 0; + + // calculate size of memory block required to store the DIB. This + // block should be big enough to hold the BITMAPINFOHEADER, the color + // table, and the bits + + dwBytesPerLine = (((wBitCount * dwWidth) + 31) / 32 * 4); + dwLen = bi.biSize + PaletteSize((LPSTR)&bi) + (dwBytesPerLine * dwHeight); + + // alloc memory block to store our bitmap + hDIB = GlobalAlloc(GHND, dwLen); + + // major bummer if we couldn't get memory block + if (!hDIB) + { + return NULL; + } + + // lock memory and get pointer to it + lpbi = (VOID FAR *)GlobalLock(hDIB); + + // use our bitmap info structure to fill in first part of + // our DIB with the BITMAPINFOHEADER + *lpbi = bi; + + // Since we don't know what the colortable and bits should contain, + // just leave these blank. Unlock the DIB and return the HDIB. + + GlobalUnlock(hDIB); + + /* return handle to the DIB */ + return hDIB; +} + + +LPSTR FAR FindDIBBits(LPSTR lpDIB) +{ + return (lpDIB + *(LPDWORD)lpDIB + PaletteSize(lpDIB)); +} + + +WORD FAR PaletteSize(LPSTR lpDIB) +{ + /* calculate the size required by the palette */ + if (IS_WIN30_DIB (lpDIB)) + return (DIBNumColors(lpDIB) * sizeof(RGBQUAD)); + else + return (DIBNumColors(lpDIB) * sizeof(RGBTRIPLE)); +} + + +WORD DIBNumColors(LPSTR lpDIB) +{ + WORD wBitCount; // DIB bit count + + /* If this is a Windows-style DIB, the number of colors in the + * color table can be less than the number of bits per pixel + * allows for (i.e. lpbi->biClrUsed can be set to some value). + * If this is the case, return the appropriate value. + */ + + if (IS_WIN30_DIB(lpDIB)) + { + DWORD dwClrUsed; + + dwClrUsed = ((LPBITMAPINFOHEADER)lpDIB)->biClrUsed; + if (dwClrUsed) + return (WORD)dwClrUsed; + } + + /* Calculate the number of colors in the color table based on + * the number of bits per pixel for the DIB. + */ + if (IS_WIN30_DIB(lpDIB)) + wBitCount = ((LPBITMAPINFOHEADER)lpDIB)->biBitCount; + else + wBitCount = ((LPBITMAPCOREHEADER)lpDIB)->bcBitCount; + + /* return number of colors based on bits per pixel */ + switch (wBitCount) + { + case 1: + return 2; + + case 4: + return 16; + + case 8: + return 256; + + default: + return 0; + } +} +/* + * Local Variables: + * mode: c + * c-basic-offset: 8 + * fill-column: 78 + * End: + */ |