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