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