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