예제 #1
0
//---------------------------------------------------------------------
//
// Function:   DIBPaint
//
// Purpose:    Painting routine for a DIB.  Calls StretchDIBits() or
//             SetDIBitsToDevice() to paint the DIB.  The DIB is
//             output to the specified DC, at the coordinates given
//             in lpDCRect.  The area of the DIB to be output is
//             given by lpDIBRect.  The specified palette is used.
//
// Parms:      hDC       == DC to do output to.
//             lpDCRect  == Rectangle on DC to do output to.
//             hDIB      == Handle to global memory with a DIB spec
//                          in it (either a BITMAPINFO or BITMAPCOREINFO
//                          followed by the DIB bits).
//             lpDIBRect == Rect of DIB to output into lpDCRect.
//             hPal      == Palette to be used.
//
// History:   Date      Reason
//             6/01/91  Created
//
//---------------------------------------------------------------------
static void DIBPaint (HDC hDC,LPRECT lpDCRect,HANDLE hDIB)
{
   LPSTR    lpDIBHdr, lpDIBBits;

   if (!hDIB)
      return;
      // Lock down the DIB, and get a pointer to the beginning of the bit
      //  buffer.
        lpDIBHdr  = GlobalLock (hDIB);
        lpDIBBits = FindDIBBits (lpDIBHdr);
      // Make sure to use the stretching mode best for color pictures.
        SetStretchBltMode (hDC, COLORONCOLOR);
        SetDIBitsToDevice (hDC,                          // hDC
                         lpDCRect->left,               // DestX
                         lpDCRect->top,                // DestY
                         RECTWIDTH (lpDCRect),         // nDestWidth
                         RECTHEIGHT (lpDCRect),        // nDestHeight
                                                                 0,              // SrcX
                         0,
 //                        (int) DIBHeight (lpDIBHdr),   // SrcY
                                                                 0,                            // nStartScan
                         (WORD) DIBHeight (lpDIBHdr),  // nNumScans
                         lpDIBBits,                    // lpBits
                         (LPBITMAPINFO) lpDIBHdr,      // lpBitsInfo
                         DIB_RGB_COLORS);              // wUsage

   GlobalUnlock (hDIB);
}
예제 #2
0
/****************************************************************************
*
*     FUNCTION: DIBToIconImage
*
*     PURPOSE:  Converts a CF_DIB memory block to an icon image
*
*     PARAMS:   LPICONIMAGE lpii          - pointer to icon image data
*               LPBYTE      lpDIB         - a pointer to the CF_DIB block
*               BOOL        bStretchToFit - TRUE to stretch, FALSE to take
*                                           the upper left corner of the DIB
*
*     RETURNS:  BOOL - TRUE for success, FALSE for failure
*
* History:
*                July '95 - Created
*
\****************************************************************************/
BOOL DIBToIconImage( LPICONIMAGE lpii, LPBYTE lpDIB, BOOL bStretch )
{
    LPBYTE    	lpNewDIB;

    // Sanity check
    if( lpDIB == NULL )
        return FALSE;

    // Let the DIB engine convert color depths if need be
    lpNewDIB = ConvertDIBFormat( (LPBITMAPINFO)lpDIB, lpii->Width, lpii->Height, lpii->Colors, bStretch );

    // Now we have a cool new DIB of the proper size/color depth
    // Lets poke it into our data structures and be done with it

    // How big is it?
    lpii->dwNumBytes = sizeof( BITMAPINFOHEADER )                    	// Header
                    + PaletteSize( (LPSTR)lpNewDIB )                    // Palette
                    + lpii->Height * BytesPerLine( (LPBITMAPINFOHEADER)lpNewDIB )	// XOR mask
                    + lpii->Height * WIDTHBYTES( lpii->Width );        	// AND mask

    // If there was already an image here, free it
    if( lpii->lpBits != NULL )
        free( lpii->lpBits );
    // Allocate enough room for the new image
    if( (lpii->lpBits = malloc( lpii->dwNumBytes )) == NULL )
    {
        free( lpii );
        return FALSE;
    }
    // Copy the bits
    memcpy( lpii->lpBits, lpNewDIB, sizeof( BITMAPINFOHEADER ) + PaletteSize( (LPSTR)lpNewDIB ) );
    // Adjust internal pointers/variables for new image
    lpii->lpbi = (LPBITMAPINFO)(lpii->lpBits);
    lpii->lpbi->bmiHeader.biHeight *= 2;
    lpii->lpXOR = FindDIBBits( (LPSTR)(lpii->lpBits) );
    memcpy( lpii->lpXOR, FindDIBBits((LPSTR)lpNewDIB), lpii->Height * BytesPerLine( (LPBITMAPINFOHEADER)lpNewDIB ) );
    lpii->lpAND = lpii->lpXOR + lpii->Height * BytesPerLine( (LPBITMAPINFOHEADER)lpNewDIB );
    memset( lpii->lpAND, 0, lpii->Height * WIDTHBYTES( lpii->Width ) );
    // Free the source
    free( lpNewDIB );
    return TRUE;
}
예제 #3
0
파일: Jpeg.cpp 프로젝트: chinalufei/Red
// load jpeg file
BOOL CJpeg::Load(LPCSTR lpstrFileName)
{
	UINT uWidth, uHeight, uWidthDW;

	// read the jpeg to a packed buffer of RGB bytes
	BYTE *lpTmpBuffer = ReadJPEGFile(lpstrFileName, &uWidth, &uHeight);
	if (lpTmpBuffer == NULL)
		return FALSE;

	// do this before DWORD-alignment!!!
	// swap red and blue for display
	BGRFromRGB(lpTmpBuffer, uWidth, uHeight);

	// now DWORD-align for display
	BYTE *lpBuffer = MakeDwordAlign(lpTmpBuffer, uWidth, uHeight, &uWidthDW);
	FreeBuffer(lpTmpBuffer);

	// flip for display
	VertFlipBuf(lpBuffer, uWidthDW, uHeight);

	BITMAPINFOHEADER bmiHeader;
	bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bmiHeader.biWidth = uWidth;
	bmiHeader.biHeight = uHeight;
	bmiHeader.biPlanes = 1;
	bmiHeader.biBitCount = 24;
	bmiHeader.biCompression = BI_RGB;
	bmiHeader.biSizeImage = 0;
	bmiHeader.biXPelsPerMeter = 0;
	bmiHeader.biYPelsPerMeter = 0;
	bmiHeader.biClrUsed = 0;
	bmiHeader.biClrImportant = 0;

    // Allocate enough memory for the new CF_DIB, and copy bits 
	DWORD dwHeaderSize = sizeof(BITMAPINFOHEADER);
	DWORD dwBitsSize = WIDTHBYTES(uWidth*24) * uHeight;
    HDIB hDIB = GlobalAlloc(GHND, dwHeaderSize + dwBitsSize); 
	if (hDIB == NULL)
		return FALSE;

    LPBYTE lpDIB = (LPBYTE)GlobalLock(hDIB); 
    memcpy(lpDIB, (LPBYTE)&bmiHeader, dwHeaderSize); 
    memcpy(FindDIBBits((LPBYTE)lpDIB), lpBuffer, dwBitsSize); 
	FreeBuffer(lpBuffer);

	if (m_pDib != NULL)
		delete m_pDib;

	m_pDib = new CDib();
	m_pDib->Attach(hDIB);

	return TRUE;
}
예제 #4
0
HBITMAP DIBToBitmap(HDIB hDIB, HPALETTE hPal)
{
    LPSTR       lpDIBHdr, lpDIBBits;  // pointer to DIB header, pointer to DIB bits
    HBITMAP     hBitmap;            // handle to device-dependent bitmap
    HDC         hDC;                    // handle to DC
    HPALETTE    hOldPal = NULL;    // handle to a palette

    // if invalid handle, return NULL 

    if (!hDIB)
        return NULL;

    // lock memory block and get a pointer to it

    lpDIBHdr = (LPSTR)GlobalLock(hDIB);

    // get a pointer to the DIB bits

    lpDIBBits = FindDIBBits(lpDIBHdr);

    // get a DC 

    hDC = GetDC(NULL);
    if (!hDC)
    {
        // clean up and return NULL

        GlobalUnlock(hDIB);
        return NULL;
    }

    // select and realize palette

    if (hPal)
        hOldPal = SelectPalette(hDC, hPal, FALSE);

    RealizePalette(hDC);

    // create bitmap from DIB info. and bits
    hBitmap = CreateDIBitmap(hDC, (LPBITMAPINFOHEADER)lpDIBHdr, CBM_INIT,
            lpDIBBits, (LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS);

    // restore previous palette
    if (hOldPal)
        SelectPalette(hDC, hOldPal, FALSE);

    // clean up
    ReleaseDC(NULL, hDC);
    GlobalUnlock(hDIB);

    // return handle to the bitmap
    return hBitmap;
}
예제 #5
0
/****************************************************************************
*
*     FUNCTION: AdjustIconImagePointers
*
*     PURPOSE:  Adjusts internal pointers in icon resource struct
*
*     PARAMS:   LPICONIMAGE lpImage - the resource to handle
*
*     RETURNS:  BOOL - TRUE for success, FALSE for failure
*
* History:
*                July '95 - Created
*
\****************************************************************************/
BOOL AdjustIconImagePointers( LPICONIMAGE lpImage )
{
    // Sanity check
    if( lpImage==NULL )
        return FALSE;
    // BITMAPINFO is at beginning of bits
    lpImage->lpbi = (LPBITMAPINFO)lpImage->lpBits;
    // Width - simple enough
    lpImage->Width = lpImage->lpbi->bmiHeader.biWidth;
    // Icons are stored in funky format where height is doubled - account for it
    lpImage->Height = (lpImage->lpbi->bmiHeader.biHeight)/2;
    // How many colors?
    lpImage->Colors = lpImage->lpbi->bmiHeader.biPlanes * lpImage->lpbi->bmiHeader.biBitCount;
    // XOR bits follow the header and color table
    lpImage->lpXOR = FindDIBBits((LPSTR)lpImage->lpbi);
    // AND bits follow the XOR bits
    lpImage->lpAND = lpImage->lpXOR + (lpImage->Height*BytesPerLine((LPBITMAPINFOHEADER)(lpImage->lpbi)));
    return TRUE;
}
예제 #6
0
// DIBToDDB	- Creates a DDB from a DIB
// hDIB   	- Device independent bitmap
HBITMAP DIBToDDB( HANDLE hDIB ) {
	HBITMAP             hBitmap;
	LPBITMAPINFOHEADER	lpbi;
	HPALETTE						hPalette = NULL;
	HPALETTE						hOldPal = NULL;
	HDC 								hDC;	
	LPSTR								lpDIBHdr, lpDIBBits;

	if ( hDIB == NULL )
		return NULL;

  lpbi = ::GetBitmapInfo( hDIB );

  if ( !::InitPalette((LPSTR)lpbi, &hPalette) )
			return FALSE;

	hDC = ::GetDC( NULL );

	if ( hPalette ) {
		// Select and realize the palette
		hOldPal = ::SelectPalette( hDC, hPalette, FALSE );
		::RealizePalette( hDC );
	}

	lpDIBHdr  = (LPSTR)lpbi;
	lpDIBBits = FindDIBBits(lpDIBHdr);

	hBitmap = ::CreateDIBitmap (hDC,
	 	                       (LPBITMAPINFOHEADER)lpDIBHdr,
	     	                   CBM_INIT,
	        	               lpDIBBits,
	            	           (LPBITMAPINFO) lpbi,
	                	       DIB_RGB_COLORS);
	if ( hPalette ) {
		::SelectPalette( hDC, hOldPal, FALSE );
		::DeleteObject( hPalette );
	}

	::ReleaseDC (NULL, hDC );

	return hBitmap;
}
예제 #7
0
BOOL CIconExtractor::AdjustIconImagePointers(LPICONIMAGE lpImage)
{
	if (!lpImage)
		return FALSE;

	// BITMAPINFO is at beginning of bits
	lpImage->lpbi = reinterpret_cast<LPBITMAPINFO>(lpImage->lpBits);
	// Width - simple enough
	lpImage->Width = lpImage->lpbi->bmiHeader.biWidth;
	// Icons are stored in funky format where height is doubled - account for it
	lpImage->Height = (lpImage->lpbi->bmiHeader.biHeight) / 2;
	// How many colors?
	lpImage->Colors = lpImage->lpbi->bmiHeader.biPlanes * lpImage->lpbi->bmiHeader.biBitCount;
	// XOR bits follow the header and color table
	lpImage->lpXOR = reinterpret_cast<PBYTE>(FindDIBBits(reinterpret_cast<LPSTR>(lpImage->lpbi)));
	// AND bits follow the XOR bits
	lpImage->lpAND = lpImage->lpXOR + (lpImage->Height * BytesPerLine(reinterpret_cast<LPBITMAPINFOHEADER>(lpImage->lpbi)));

	return TRUE;
}
예제 #8
0
DWORD DIBPrint (HDC hPrnDC,
								HANDLE hDIB,
                LPRECT lpPrintRect,
                  WORD wUnits,
                 DWORD dwROP,
                  BOOL fBanding,
									BOOL fUse31APIs)
	{
	 RECT           rect;
	 LPSTR          lpDIBHdr, lpBits;


      // Do some setup (like getting pointers to the DIB and its header,
			//  and a printer DC).  Also, set the global gbUseEscapes to force
      //  using printer escapes or the 3.1 printing API.

   if (!hDIB)
			return 0;

   gbUseEscapes = !fUse31APIs;
	 lpDIBHdr     = (LPSTR)GlobalLock (hDIB);
   lpBits       = FindDIBBits (lpDIBHdr);

	 if (hPrnDC)
      {
      SetStretchBltMode (hPrnDC, COLORONCOLOR);
      TranslatePrintRect (hPrnDC,
                          lpPrintRect,
                          wUnits,
                          (WORD) DIBWidth (lpDIBHdr),
                          (WORD) DIBHeight (lpDIBHdr));


         // Initialize the abort procedure.  Then STARTDOC.

			bAbort      = FALSE;

	
      if (fBanding)
				 BandDIBToPrinter (hPrnDC, lpDIBHdr, lpBits, lpPrintRect);
      else
         {
            // When not doing banding, call PrintABand() to dump the
            //  entire page to the printer in one shot (i.e. give it
						//  a band that covers the entire printing rectangle,
						//  and tell it to print graphics and text).

				 rect = *lpPrintRect;

				PrintABand (hPrnDC,
															lpPrintRect,
															&rect,
															TRUE,
															TRUE,
															lpDIBHdr,
															lpBits);


				 // Non-banding devices need the NEWFRAME or EndPage() call.

				 }



		 }

				 // All done, clean up.


	 GlobalUnlock (hDIB);
	 I_UNUSED(dwROP);
	 return 1;
}
예제 #9
0
파일: ImagePcx.cpp 프로젝트: chinalufei/Red
//******************* 保存为PCX (由CDib对象) ***********************
BOOL LanImage::SavePcx(LPCTSTR lpstrFileName, CDib* pDib)
{
    int i = 0;
	if (pDib == NULL)
		return FALSE;

	HDIB hDib = CopyHandle(pDib->GetHandle());
	if (hDib == NULL)
		return FALSE;

	CDib* pDibTmp = new CDib();
	pDibTmp->Attach(hDib);

	UINT uWidth  = pDibTmp->GetWidth();
	UINT uHeight = pDibTmp->GetHeight();

	// 当打开的图像BitCount不为8时,转为8位格式
	if (pDibTmp->GetBitCount() != 8)
		pDibTmp->ConvertFormat(8);

	// make PCX header
	PCXHEAD header;
	memset((LPBYTE)&header, 0, sizeof(PCXHEAD));
	header.manufacturer = 0x0A;
	header.version = 5;
	header.encoding = 1;
	header.bit_per_pixel = 8;
	//header.bit_per_pixel = 24;
	header.xmin = 0;
	header.ymin = 0;
	header.xmax = uWidth-1;
	header.ymax = uHeight-1;
	//header.Xresolution;
	//header.Yresolution;
	header.palette[0] = (BYTE)0x00;  // for correct process for mono
	header.palette[1] = (BYTE)0x00;
	header.palette[2] = (BYTE)0x00;
	header.palette[3] = (BYTE)0xff;
	header.palette[4] = (BYTE)0xff;
	header.palette[5] = (BYTE)0xff;
	//header.palette[48];
	header.reserved = 0;
	header.color_planes = 1;
	header.byte_per_line = uWidth;
	header.palette_type = 1;
	//filler[58];

	// construct PCX palette from DIB color table
	PCXPALETTE palette[256];
	PALETTEENTRY PaletteColors[256];
	pDibTmp->GetPalette()->GetPaletteEntries(0, 256, PaletteColors);
	for (i=0;i<256;i++) 
	{
		palette[i].rgbRed   = PaletteColors[i].peRed;
		palette[i].rgbGreen = PaletteColors[i].peGreen;
		palette[i].rgbBlue  = PaletteColors[i].peBlue;
	}

	// get bits ptr
	HDIB hDIB = CopyHandle(pDibTmp->GetHandle());
	delete pDibTmp;
	LPBYTE lpDIB = (LPBYTE)GlobalLock(hDIB);
	BYTE* lpBuffer = (BYTE *)FindDIBBits(lpDIB);
	WORD wWidthBytes = (WORD)BytesPerLine(lpDIB);

	/*** Open the PCX file ***/
	FILE *outFile;
	if ((outFile=fopen(lpstrFileName,"wb")) == NULL)
	{
		GlobalUnlock(hDIB);
		GlobalFree(hDIB);
		return FALSE;
	}

	/*** Write the header ***/
	fwrite((char *)&header, sizeof(PCXHEAD), 1, outFile);

	/*** Write image data ***/
	for ( i=(int)uHeight-1; i>=0; --i)
	{
		if (! WritePCXLine(header.byte_per_line, lpBuffer+i*wWidthBytes, outFile))
		{
			fclose(outFile);
			GlobalUnlock(hDIB);
			GlobalFree(hDIB);
			return FALSE;
		}
	}

	/*** Write the palette data ***/
	fputc(0x0c, outFile);
	fwrite((char *)palette, 1, sizeof(palette), outFile);

	// clear & close
	fclose(outFile);
	GlobalUnlock(hDIB);
	GlobalFree(hDIB);

	return TRUE;
}
예제 #10
0
/****************************************************************************
*
*     FUNCTION: ReadBMPFile
*
*     PURPOSE:  Reads a BMP file into CF_DIB format
*
*     PARAMS:   LPCTSTR szFileName - the name of the file to read
*
*     RETURNS:  LPBYTE - pointer to the CF_DIB, NULL for failure
*
* History:
*                July '95 - Created
*
\****************************************************************************/
LPBYTE ReadBMPFile( LPCTSTR szFileName )
{
    HANDLE            	hFile;
    BITMAPFILEHEADER    bfh;
    DWORD            	dwBytes;
    LPBYTE            	lpDIB = NULL, lpTemp = NULL;
    WORD                wPaletteSize = 0;
    DWORD            	dwBitsSize = 0;

    // Open the file
    if( (hFile=CreateFile( szFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE )
    {
        MessageBox( NULL, "Error opening file", szFileName, MB_OK );
        return NULL;
    }
    // Read the header
    if( ( ! ReadFile( hFile, &bfh, sizeof(BITMAPFILEHEADER), &dwBytes, NULL ) ) || ( dwBytes != sizeof( BITMAPFILEHEADER ) ) )
    {
        CloseHandle( hFile );
        MessageBox( NULL, "Error reading file", szFileName, MB_OK );
        return NULL;
    }
    // Does it look like a BMP file?
    if( ( bfh.bfType != 0x4d42 ) || (bfh.bfReserved1!=0) || (bfh.bfReserved2!=0) )
    {
        CloseHandle( hFile );
        MessageBox( NULL, "Not a recognised BMP format file", szFileName, MB_OK );
        return NULL;
    }
    // Allocate some memory
    if( (lpDIB = malloc( sizeof( BITMAPINFO ) )) == NULL )
    {
        CloseHandle( hFile );
        MessageBox( NULL, "Failed to allocate memory for DIB", szFileName, MB_OK );
        return NULL;
    }
    // Read in the BITMAPINFOHEADER
    if( (!ReadFile( hFile, lpDIB, sizeof(BITMAPINFOHEADER), &dwBytes, NULL )) || (dwBytes!=sizeof(BITMAPINFOHEADER)) )
    {
        CloseHandle( hFile );
        free( lpDIB );
        MessageBox( NULL, "Error reading file", szFileName, MB_OK );
        return NULL;
    }
    if( ((LPBITMAPINFOHEADER)lpDIB)->biSize != sizeof( BITMAPINFOHEADER ) )
    {
        CloseHandle( hFile );
        free( lpDIB );
        MessageBox( NULL, "OS/2 style BMPs Not Supported", szFileName, MB_OK );
        return NULL;
    }
    // How big are the elements?
    wPaletteSize = PaletteSize((LPSTR)lpDIB);
    dwBitsSize = ((LPBITMAPINFOHEADER)lpDIB)->biHeight * BytesPerLine((LPBITMAPINFOHEADER)lpDIB);
    // realloc to account for the total size of the DIB
    if( (lpTemp = realloc( lpDIB, sizeof( BITMAPINFOHEADER ) + wPaletteSize + dwBitsSize )) == NULL )
    {
        CloseHandle( hFile );
        MessageBox( NULL, "Failed to allocate memory for DIB", szFileName, MB_OK );
        free( lpDIB );
        return NULL;
    }
    lpDIB = lpTemp;
    // If there is a color table, read it
    if( wPaletteSize != 0 )
    {
        if( (!ReadFile( hFile, ((LPBITMAPINFO)lpDIB)->bmiColors, wPaletteSize, &dwBytes, NULL )) || (dwBytes!=wPaletteSize) )
        {
            CloseHandle( hFile );
            free( lpDIB );
            MessageBox( NULL, "Error reading file", szFileName, MB_OK );
            return NULL;
        }
    }
    // Seek to the bits
    // checking against 0 in case some bogus app didn't set this element
    if( bfh.bfOffBits != 0 )
    {
        if( SetFilePointer( hFile, bfh.bfOffBits, NULL, FILE_BEGIN ) == 0xffffffff )
        {
            CloseHandle( hFile );
            free( lpDIB );
            MessageBox( NULL, "Error reading file", szFileName, MB_OK );
            return NULL;
        }
    }
    // Read the image bits
    if( (!ReadFile( hFile, FindDIBBits(lpDIB), dwBitsSize, &dwBytes, NULL )) || (dwBytes!=dwBitsSize) )
    {
        CloseHandle( hFile );
        free( lpDIB );
        MessageBox( NULL, "Error reading file", szFileName, MB_OK );
        return NULL;
    }
    // clean up
    CloseHandle( hFile );
    return lpDIB;
}
예제 #11
0
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);
    }
예제 #12
0
파일: IP.cpp 프로젝트: neochang/PictView
/****************************************************
	FFTDIB()

	参数:

		hDIB为输入的DIB句柄

	返回值:

		成功为TRUE;失败为FALSE

	说明:

		本函数实现DIB位图的快速傅立叶变换
****************************************************/
BOOL FFTDIB(HDIB hDIB)
{
	if (hDIB == NULL)
		return FALSE;

	// start wait cursor
	WaitCursorBegin();

	HDIB hDib = NULL;
	HDIB hNewDib = NULL;
	// we only convolute 24bpp DIB, so first convert DIB to 24bpp
	WORD wBitCount = DIBBitCount(hDIB);
	if (wBitCount != 24)
	{
		hNewDib = ConvertDIBFormat(hDIB, 24, NULL);
		hDib = CopyHandle(hNewDib);
	}
	else
	{
		hNewDib = CopyHandle(hDIB);
		hDib = CopyHandle(hDIB);
	}

	if (hNewDib == NULL && hDib == NULL)
	{
		WaitCursorEnd();
		return FALSE;
	}

	// process!
	LPBYTE lpSrcDIB = (LPBYTE)GlobalLock(hDib);
	LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDib);
	LPBYTE lpInput = FindDIBBits(lpSrcDIB);
	LPBYTE lpOutput = FindDIBBits(lpDIB);
	int nWidth = DIBWidth(lpSrcDIB);
	int nHeight = DIBHeight(lpSrcDIB);
	
	int w=1,h=1,wp=0,hp=0;
	while(w*2<=nWidth)
	{
		w*=2;
		wp++;
	}
	while(h*2<=nHeight)
	{
		h*=2;
		hp++;
	}
	int x,y;
	BYTE *lpPoints=new BYTE[nWidth*nHeight];
	GetPoints(nWidth,nHeight,lpInput,lpPoints);

	COMPLEX *TD=new COMPLEX[w*h];
	COMPLEX *FD=new COMPLEX[w*h];

	for(y=0;y<h;y++)
	{
		for(x=0;x<w;x++)
		{
			TD[x+w*y].re=Point(x,y);
			TD[x+w*y].im=0;
		}
	}

	for(y=0;y<h;y++)
	{
		FFT(&TD[w*y],&FD[w*y],wp);
	}
	for(y=0;y<h;y++)
	{
		for(x=0;x<w;x++)
		{
			TD[y+h*x]=FD[x+w*y];
//			TD[x+w*y]=FD[x*h+y];
		}
	}
	for(x=0;x<w;x++)
	{
		FFT(&TD[x*h],&FD[x*h],hp);
	}

	memset(lpPoints,0,nWidth*nHeight);
	double m;
	for(y=0;y<h;y++)
	{
		for(x=0;x<w;x++)
		{
			m=sqrt(FD[x*h+y].re*FD[x*h+y].re+FD[x*h+y].im*FD[x*h+y].im)/100;
			if (m>255) m=255;
			Point((x<w/2?x+w/2:x-w/2),nHeight-1-(y<h/2?y+h/2:y-h/2))=(BYTE)(m);
		}
	}
	delete TD;
	delete FD;
	PutPoints(nWidth,nHeight,lpOutput,lpPoints);
	delete lpPoints;

	// recover
	DWORD dwSize = GlobalSize(hDib);
	memcpy(lpSrcDIB, lpDIB, dwSize);
	GlobalUnlock(hDib);
	GlobalUnlock(hNewDib);
	if (wBitCount != 24)
	{
		hNewDib = ConvertDIBFormat(hDib, wBitCount, NULL);

		lpSrcDIB = (LPBYTE)GlobalLock(hDIB);
		lpDIB = (LPBYTE)GlobalLock(hNewDib);
		dwSize = GlobalSize(hNewDib);
		memcpy(lpSrcDIB, lpDIB, dwSize);
		GlobalUnlock(hDIB);
		GlobalUnlock(hNewDib);
	}
	else
	{
		lpSrcDIB = (LPBYTE)GlobalLock(hDIB);
		lpDIB = (LPBYTE)GlobalLock(hDib);
		dwSize = GlobalSize(hDib);
		memcpy(lpSrcDIB, lpDIB, dwSize);
		GlobalUnlock(hDIB);
		GlobalUnlock(hDib);
	}

	// cleanup
	GlobalFree(hDib);
	GlobalFree(hNewDib);

	// return
	WaitCursorEnd();
	return TRUE;
}
예제 #13
0
파일: IP.cpp 프로젝트: neochang/PictView
/****************************************************
	WALhDIB()

	参数:

		hDIB为输入的DIB句柄

	返回值:

		成功为TRUE;失败为FALSE

	说明:

		本函数实现DIB位图的快速沃尔什-哈达玛变换
****************************************************/
BOOL WALhDIB(HDIB hDIB)
{
	if (hDIB == NULL)
		return FALSE;

	// start wait cursor
	WaitCursorBegin();

	HDIB hDib = NULL;
	HDIB hNewDib = NULL;
	// we only convolute 24bpp DIB, so first convert DIB to 24bpp
	WORD wBitCount = DIBBitCount(hDIB);
	if (wBitCount != 24)
	{
		hNewDib = ConvertDIBFormat(hDIB, 24, NULL);
		hDib = CopyHandle(hNewDib);
	}
	else
	{
		hNewDib = CopyHandle(hDIB);
		hDib = CopyHandle(hDIB);
	}

	if (hNewDib == NULL && hDib == NULL)
	{
		WaitCursorEnd();
		return FALSE;
	}

	// process!
	LPBYTE lpSrcDIB = (LPBYTE)GlobalLock(hDib);
	LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDib);
	LPBYTE lpInput = FindDIBBits(lpSrcDIB);
	LPBYTE lpOutput = FindDIBBits(lpDIB);
	int nWidth = DIBWidth(lpSrcDIB);
	int nHeight = DIBHeight(lpSrcDIB);

	int w=1,h=1,wp=0,hp=0;
	while(w*2<=nWidth)
	{
		w*=2;
		wp++;
	}
	while(h*2<=nHeight)
	{
		h*=2;
		hp++;
	}
	int x,y;
	BYTE *lpPoints=new BYTE[nWidth*nHeight];
	GetPoints(nWidth,nHeight,lpInput,lpPoints);

	double *f=new double[w*h];
	double *W=new double[w*h];

	for(y=0;y<h;y++)
	{
		for(x=0;x<w;x++)
		{
			f[x+y*w]=Point(x,y);
		}
	}

	for(y=0;y<h;y++)
	{
		WALh(f+w*y,W+w*y,wp);
	}
	for(y=0;y<h;y++)
	{
		for(x=0;x<w;x++)
		{
			f[x*h+y]=W[x+w*y];
		}
	}
	for(x=0;x<w;x++)
	{
		WALh(f+x*h,W+x*h,hp);
	}
	double a;
	memset(lpPoints,0,nWidth*nHeight);

	for(y=0;y<h;y++)
	{
		for(x=0;x<w;x++)
		{
			a=fabs(W[x*h+y]*1000);
			if (a>255) a=255;
			Point(x,nHeight-y-1)=(BYTE)a;
		}
	}
	delete f;
	delete W;
	PutPoints(nWidth,nHeight,lpOutput,lpPoints);
	delete lpPoints;

	// recover
	DWORD dwSize = GlobalSize(hDib);
	memcpy(lpSrcDIB, lpDIB, dwSize);
	GlobalUnlock(hDib);
	GlobalUnlock(hNewDib);
	if (wBitCount != 24)
	{
		hNewDib = ConvertDIBFormat(hDib, wBitCount, NULL);

		lpSrcDIB = (LPBYTE)GlobalLock(hDIB);
		lpDIB = (LPBYTE)GlobalLock(hNewDib);
		dwSize = GlobalSize(hNewDib);
		memcpy(lpSrcDIB, lpDIB, dwSize);
		GlobalUnlock(hDIB);
		GlobalUnlock(hNewDib);
	}
	else
	{
		lpSrcDIB = (LPBYTE)GlobalLock(hDIB);
		lpDIB = (LPBYTE)GlobalLock(hDib);
		dwSize = GlobalSize(hDib);
		memcpy(lpSrcDIB, lpDIB, dwSize);
		GlobalUnlock(hDIB);
		GlobalUnlock(hDib);
	}

	// cleanup
	GlobalFree(hDib);
	GlobalFree(hNewDib);

	// return
	WaitCursorEnd();
	return TRUE;
}
예제 #14
0
BOOL FAR PaintDIB(HDC      hDC,
                  LPRECT   lpDCRect,
                  HDIB     hDIB,
                  LPRECT   lpDIBRect,
                  HPALETTE hPal)
{
   LPSTR    lpDIBHdr;            // Pointer to BITMAPINFOHEADER
   LPSTR    lpDIBBits;           // Pointer to DIB bits
   BOOL     bSuccess=FALSE;      // Success/fail flag
   HPALETTE hOldPal=NULL;        // Previous palette

   /* Check for valid DIB handle */
   if (!hDIB)
      return FALSE;

   /* Lock down the DIB, and get a pointer to the beginning of the bit
    *  buffer
    */
   lpDIBHdr  = GlobalLock(hDIB);
   lpDIBBits = FindDIBBits(lpDIBHdr);

   /* Select and realize our palette as background */
   if (hPal)
   {
      hOldPal = SelectPalette(hDC, hPal, TRUE);
      RealizePalette(hDC);
   }

   /* Make sure to use the stretching mode best for color pictures */
   SetStretchBltMode(hDC, COLORONCOLOR);

   /* Determine whether to call StretchDIBits() or SetDIBitsToDevice() */
   if ((RECTWIDTH(lpDCRect)  == RECTWIDTH(lpDIBRect)) &&
       (RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect)))
      bSuccess = SetDIBitsToDevice(hDC,                        // hDC
                                   lpDCRect->left,             // DestX
                                   lpDCRect->top,              // DestY
                                   RECTWIDTH(lpDCRect),        // nDestWidth
                                   RECTHEIGHT(lpDCRect),       // nDestHeight
                                   lpDIBRect->left,            // SrcX
                                   (int)DIBHeight(lpDIBHdr) -
                                      lpDIBRect->top - 
                                      RECTHEIGHT(lpDIBRect),   // SrcY
                                   0,                          // nStartScan
                                   (WORD)DIBHeight(lpDIBHdr),  // nNumScans
                                   lpDIBBits,                  // lpBits
                                   (LPBITMAPINFO)lpDIBHdr,     // lpBitsInfo
                                   DIB_RGB_COLORS);            // wUsage
   else 
      bSuccess = StretchDIBits(hDC,                            // hDC
                               lpDCRect->left,                 // DestX
                               lpDCRect->top,                  // DestY
                               RECTWIDTH(lpDCRect),            // nDestWidth
                               RECTHEIGHT(lpDCRect),           // nDestHeight
                               lpDIBRect->left,                // SrcX
                               lpDIBRect->top,                 // SrcY
                               RECTWIDTH(lpDIBRect),           // wSrcWidth
                               RECTHEIGHT(lpDIBRect),          // wSrcHeight
                               lpDIBBits,                      // lpBits
                               (LPBITMAPINFO)lpDIBHdr,         // lpBitsInfo
                               DIB_RGB_COLORS,                 // wUsage
                               SRCCOPY);                       // dwROP

   /* Unlock the memory block */
   GlobalUnlock(hDIB);

   /* Reselect old palette */
   if (hOldPal)
     SelectPalette(hDC, hOldPal, FALSE);

   /* Return with success/fail flag */
   return bSuccess;
}
예제 #15
0
파일: IP.cpp 프로젝트: neochang/PictView
/************************************************************************* 
 * 
 * MedianFilterDIB() 
 * 
 * Parameters: 
 * 
 * HDIB hDib        - objective DIB handle
 * 
 * Return Value: 
 * 
 * BOOL             - True is success, else False
 * 
 * Description: 
 * 
 * This is the media filtering function to DIB
 * 
 ************************************************************************/ 
BOOL MedianFilterDIB(HDIB hDib) 
{
	WaitCursorBegin();

	HDIB hNewDib = NULL;
	// we only convolute 24bpp DIB, so first convert DIB to 24bpp
	WORD wBitCount = DIBBitCount(hDib);
	if (wBitCount != 24)
		hNewDib = ConvertDIBFormat(hDib, 24, NULL);
	else
		hNewDib = CopyHandle(hDib);

	if (! hNewDib)
	{
		WaitCursorEnd();
		return FALSE;
	}

	// new DIB attributes
	WORD wDIBWidth = (WORD)DIBWidth(hNewDib);
	WORD wDIBHeight = (WORD)DIBHeight(hNewDib);
	WORD wBytesPerLine = (WORD)BytesPerLine(hNewDib);
	DWORD dwImageSize = wBytesPerLine * wDIBHeight;

	// Allocate and lock memory for filtered image data
	HGLOBAL hFilteredBits = GlobalAlloc(GHND, dwImageSize);
	if (!hFilteredBits) 
	{
		WaitCursorEnd();
		return FALSE;
	}
	LPBYTE lpDestImage = (LPBYTE)GlobalLock(hFilteredBits);

	// get bits address in DIB
	LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDib);
	LPBYTE lpDIBits = FindDIBBits(lpDIB);

	// convolute...
	for (int i=1; i<wDIBHeight-1; i++) 
		for (int j=1; j<wDIBWidth-1; j++) 
		{
			int  red=0, green=0, blue=0; 
			DoMedianFilterDIB(&red, &green, &blue, i, j, wBytesPerLine, lpDIBits);

			LONG lOffset= PIXEL_OFFSET(i,j, wBytesPerLine);
			*(lpDestImage + lOffset++) = BOUND(blue, 0, 255);
			*(lpDestImage + lOffset++) = BOUND(green, 0, 255);
			*(lpDestImage + lOffset)   = BOUND(red, 0, 255);
		}

	// a filtered image is available in lpDestImage
	// copy it to DIB bits
	memcpy(lpDIBits, lpDestImage, dwImageSize);

	// cleanup temp buffers
	GlobalUnlock(hFilteredBits);
	GlobalFree(hFilteredBits);
	GlobalUnlock(hNewDib);

	// rebuild hDib
	HDIB hTmp = NULL;
	if (wBitCount != 24)
		hTmp = ConvertDIBFormat(hNewDib, wBitCount, NULL);
	else
		hTmp = CopyHandle(hNewDib);
	GlobalFree(hNewDib);
	DWORD dwSize = GlobalSize(hTmp);
	memcpy((LPBYTE)GlobalLock(hDib), (LPBYTE)GlobalLock(hTmp), dwSize);
	GlobalUnlock(hTmp);
	GlobalFree(hTmp);
	GlobalUnlock(hDib);
	WaitCursorEnd();

	return TRUE;
}
예제 #16
0
/****************************************************************************
*
*     FUNCTION: ConvertDIBFormat
*
*     PURPOSE:  Creates a new DIB of the requested format, copies the source
*               image to the new DIB.
*
*     PARAMS:   LPBITMAPINFO lpSrcDIB - the source CF_DIB
*               UINT         nWidth   - width for new DIB
*               UINT         nHeight  - height for new DIB
*               UINT         nbpp     - bpp for new DIB
*               BOOL         bStretch - TRUE to stretch source to dest
*                                       FALSE to take upper left of image
*
*     RETURNS:  LPBYTE - pointer to new CF_DIB memory block with new image
*               NULL on failure
*
* History:
*                July '95 - Created
*
\****************************************************************************/
LPBYTE ConvertDIBFormat( LPBITMAPINFO lpSrcDIB, UINT nWidth, UINT nHeight, UINT nbpp, BOOL bStretch )
{
    LPBITMAPINFO    lpbmi = NULL;
    LPBYTE        	lpSourceBits, lpTargetBits, lpResult;
    HDC            	hDC = NULL, hSourceDC, hTargetDC;
    HBITMAP        	hSourceBitmap, hTargetBitmap, hOldTargetBitmap, hOldSourceBitmap;
    DWORD        	dwSourceBitsSize, dwTargetBitsSize, dwTargetHeaderSize;

    // Allocate and fill out a BITMAPINFO struct for the new DIB
    // Allow enough room for a 256-entry color table, just in case
    dwTargetHeaderSize = sizeof( BITMAPINFO ) + ( 256 * sizeof( RGBQUAD ) );
    lpbmi = malloc( dwTargetHeaderSize );
    lpbmi->bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
    lpbmi->bmiHeader.biWidth = nWidth;
    lpbmi->bmiHeader.biHeight = nHeight;
    lpbmi->bmiHeader.biPlanes = 1;
    lpbmi->bmiHeader.biBitCount = nbpp;
    lpbmi->bmiHeader.biCompression = BI_RGB;
    lpbmi->bmiHeader.biSizeImage = 0;
    lpbmi->bmiHeader.biXPelsPerMeter = 0;
    lpbmi->bmiHeader.biYPelsPerMeter = 0;
    lpbmi->bmiHeader.biClrUsed = 0;
    lpbmi->bmiHeader.biClrImportant = 0;
    // Fill in the color table
    if( ! CopyColorTable( lpbmi, (LPBITMAPINFO)lpSrcDIB ) )
    {
        free( lpbmi );
        return NULL;
    }

    // Gonna use DIBSections and BitBlt() to do the conversion, so make 'em
    hDC = GetDC( NULL );
    hTargetBitmap = CreateDIBSection( hDC, lpbmi, DIB_RGB_COLORS, &lpTargetBits, NULL, 0 );
    hSourceBitmap = CreateDIBSection( hDC, lpSrcDIB, DIB_RGB_COLORS, &lpSourceBits, NULL, 0 );
    hSourceDC = CreateCompatibleDC( hDC );
    hTargetDC = CreateCompatibleDC( hDC );

    // Flip the bits on the source DIBSection to match the source DIB
    dwSourceBitsSize = lpSrcDIB->bmiHeader.biHeight * BytesPerLine(&(lpSrcDIB->bmiHeader));
    dwTargetBitsSize = lpbmi->bmiHeader.biHeight * BytesPerLine(&(lpbmi->bmiHeader));
    memcpy( lpSourceBits, FindDIBBits((LPSTR)lpSrcDIB), dwSourceBitsSize );

    // Select DIBSections into DCs
    hOldSourceBitmap = SelectObject( hSourceDC, hSourceBitmap );
    hOldTargetBitmap = SelectObject( hTargetDC, hTargetBitmap );

    // Set the color tables for the DIBSections
    if( lpSrcDIB->bmiHeader.biBitCount <= 8 )
        SetDIBColorTable( hSourceDC, 0, 1 << lpSrcDIB->bmiHeader.biBitCount, lpSrcDIB->bmiColors );
    if( lpbmi->bmiHeader.biBitCount <= 8 )
        SetDIBColorTable( hTargetDC, 0, 1 << lpbmi->bmiHeader.biBitCount, lpbmi->bmiColors );

    // If we are asking for a straight copy, do it
    if( (lpSrcDIB->bmiHeader.biWidth==lpbmi->bmiHeader.biWidth) && (lpSrcDIB->bmiHeader.biHeight==lpbmi->bmiHeader.biHeight) )
    {
        BitBlt( hTargetDC, 0, 0, lpbmi->bmiHeader.biWidth, lpbmi->bmiHeader.biHeight, hSourceDC, 0, 0, SRCCOPY );
    }
    else
    {
        // else, should we stretch it?
        if( bStretch )
        {
            SetStretchBltMode( hTargetDC, COLORONCOLOR );
            StretchBlt( hTargetDC, 0, 0, lpbmi->bmiHeader.biWidth, lpbmi->bmiHeader.biHeight, hSourceDC, 0, 0, lpSrcDIB->bmiHeader.biWidth, lpSrcDIB->bmiHeader.biHeight, SRCCOPY );
        }
        else
        {
            // or just take the upper left corner of the source
            BitBlt( hTargetDC, 0, 0, lpbmi->bmiHeader.biWidth, lpbmi->bmiHeader.biHeight, hSourceDC, 0, 0, SRCCOPY );
        }
    }

    // Clean up and delete the DCs
    SelectObject( hSourceDC, hOldSourceBitmap );
    SelectObject( hSourceDC, hOldTargetBitmap );
    DeleteDC( hSourceDC );
    DeleteDC( hTargetDC );
    ReleaseDC( NULL, hDC );

    // Flush the GDI batch, so we can play with the bits
    GdiFlush();

    // Allocate enough memory for the new CF_DIB, and copy bits
    lpResult = malloc( dwTargetHeaderSize + dwTargetBitsSize );
    memcpy( lpResult, lpbmi, dwTargetHeaderSize );
    memcpy( FindDIBBits( lpResult ), lpTargetBits, dwTargetBitsSize );

    // final cleanup
    DeleteObject( hTargetBitmap );
    DeleteObject( hSourceBitmap );
    free( lpbmi );

    return lpResult;
}
예제 #17
0
파일: IP.cpp 프로젝트: neochang/PictView
/************************************************************************* 
 * 
 * ConvoluteDIB() 
 * 
 * Parameters: 
 * 
 * HDIB hDib        - objective DIB handle
 * KERNEL *lpKernel - pointer of kernel used to convolute with DIB
 * int Strength     - operation strength set to the convolute
 * int nKernelNum   - kernel number used to convolute
 * 
 * Return Value: 
 * 
 * BOOL             - True is success, else False
 * 
 * Description: 
 * 
 * This is the generic convolute function to DIB
 * 
 ************************************************************************/ 
BOOL ConvoluteDIB(HDIB hDib, KERNEL *lpKernel, int Strength, int nKernelNum) 
{
	WaitCursorBegin();

	HDIB hNewDib = NULL;
	// we only convolute 24bpp DIB, so first convert DIB to 24bpp
	WORD wBitCount = DIBBitCount(hDib);
	if (wBitCount != 24)
		hNewDib = ConvertDIBFormat(hDib, 24, NULL);
	else
		hNewDib = CopyHandle(hDib);

	if (! hNewDib)
	{
		WaitCursorEnd();
		return FALSE;
	}

	// new DIB attributes
	WORD wDIBWidth = (WORD)DIBWidth(hNewDib);
	WORD wDIBHeight = (WORD)DIBHeight(hNewDib);
	WORD wBytesPerLine = (WORD)BytesPerLine(hNewDib);
	DWORD dwImageSize = wBytesPerLine * wDIBHeight;

	// Allocate and lock memory for filtered image data
	HGLOBAL hFilteredBits = GlobalAlloc(GHND, dwImageSize);
	if (!hFilteredBits) 
	{
		WaitCursorEnd();
		return FALSE;
	}
	LPBYTE lpDestImage = (LPBYTE)GlobalLock(hFilteredBits);

	// get bits address in DIB
	LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDib);
	LPBYTE lpDIBits = FindDIBBits(lpDIB);

	// convolute...
	for (int i=1; i<wDIBHeight-1; i++) 
		for (int j=1; j<wDIBWidth-1; j++) 
		{
			int  red=0, green=0, blue=0; 

			for (int k=0; k<nKernelNum; ++k)
			{
				int r=0, g=0, b=0; 
				DoConvoluteDIB(&r, &g, &b, i, j, 
					wBytesPerLine, lpDIBits, lpKernel+k);
				if (r > red)
					red = r;
				if (g > green)
					green = g;
				if (b > blue)
					blue = b;
				//red += r; green += g; blue += b;
			}

			// original RGB value in center pixel  (j, i)
			LONG lOffset= PIXEL_OFFSET(i,j, wBytesPerLine);
			BYTE OldB = *(lpDIBits + lOffset++);
			BYTE OldG = *(lpDIBits + lOffset++);
			BYTE OldR = *(lpDIBits + lOffset);
			// When we get here, red, green and blue have the new RGB value.
			if (Strength != 10) 
			{
				// Interpolate pixel data
				red   = OldR + (((red - OldR) * Strength) / 10);
				green = OldG + (((green - OldG) * Strength) / 10);
				blue  = OldB + (((blue - OldB) * Strength) / 10);
			}

			lOffset= PIXEL_OFFSET(i,j, wBytesPerLine);
			*(lpDestImage + lOffset++) = BOUND(blue, 0, 255);
			*(lpDestImage + lOffset++) = BOUND(green, 0, 255);
			*(lpDestImage + lOffset)   = BOUND(red, 0, 255);
		}

	// a filtered image is available in lpDestImage
	// copy it to DIB bits
	memcpy(lpDIBits, lpDestImage, dwImageSize);

	// cleanup temp buffers
	GlobalUnlock(hFilteredBits);
	GlobalFree(hFilteredBits);
	GlobalUnlock(hNewDib);

	// rebuild hDib
	HDIB hTmp = NULL;
	if (wBitCount != 24)
		hTmp = ConvertDIBFormat(hNewDib, wBitCount, NULL);
	else
		hTmp = CopyHandle(hNewDib);
	GlobalFree(hNewDib);
	DWORD dwSize = GlobalSize(hTmp);
	memcpy((LPBYTE)GlobalLock(hDib), (LPBYTE)GlobalLock(hTmp), dwSize);
	GlobalUnlock(hTmp);
	GlobalFree(hTmp);
	GlobalUnlock(hDib);
	WaitCursorEnd();

	return TRUE;
}