⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dibit.c

📁 dib bmp source code
💻 C
📖 第 1 页 / 共 2 页
字号:
 *  PURPOSE    : Given a BITMAPINFOHEADER, create a palette based on 
 *		 the color table.
 *		 
 *									    *
 *  RETURNS    : non-zero - handle of a corresponding palette 
 *		 zero - unable to create palette
 *									    *
 ****************************************************************************/
HPALETTE PASCAL NEAR MakeDIBPalette(LPBITMAPINFOHEADER lpInfo)
{
    NPLOGPALETTE npPal;
    RGBQUAD far *lpRGB;
    HPALETTE hLogPal; 
    WORD i;

    /* since biClrUsed field was filled during the loading of the DIB,
    ** we know it contains the number of colors in the color table.
    */
    if (lpInfo->biClrUsed)
    {
	npPal = (NPLOGPALETTE)LocalAlloc(LMEM_FIXED, sizeof(LOGPALETTE) + 
				(WORD)lpInfo->biClrUsed * sizeof(PALETTEENTRY));
	if (!npPal)
	    return(FALSE);

	npPal->palVersion = 0x300;
        npPal->palNumEntries = (WORD)lpInfo->biClrUsed;

	/* get pointer to the color table */
	lpRGB = (RGBQUAD FAR *)((LPSTR)lpInfo + lpInfo->biSize);

	/* copy colors from the color table to the LogPalette structure */
        for (i = 0; i < (WORD)lpInfo->biClrUsed; i++, lpRGB++)
	{
	    npPal->palPalEntry[i].peRed = lpRGB->rgbRed;
	    npPal->palPalEntry[i].peGreen = lpRGB->rgbGreen;
	    npPal->palPalEntry[i].peBlue = lpRGB->rgbBlue;
	    npPal->palPalEntry[i].peFlags = 0;
	}

	hLogPal = CreatePalette((LPLOGPALETTE)npPal);
	LocalFree((HANDLE)npPal);
	return(hLogPal);
    }

    /* 24-bit DIB with no color table.  return default palette.  Another
    ** option would be to create a 256 color "rainbow" palette to provide
    ** some good color choices.
    */
    else
	return(GetStockObject(DEFAULT_PALETTE));
}

/****************************************************************************
 *									    *
 *  FUNCTION   : PaintDIB(hWnd)						    *
 *									    *
 *  PURPOSE    : Paint the currently loaded DIB using the options chosen
 *		 by the user.
 *									    *
 *  RETURNS    : None.
 *									    *
 ****************************************************************************/
void PASCAL NEAR PaintDIB(HWND hWnd)
{
    PAINTSTRUCT ps;
    HDC hDC;
    RECT Rectangle;
    LPBITMAPINFOHEADER lpInfo;
    LPBITMAPINFOHEADER lpHeader;
    HPALETTE hOldPal;
    WORD wDIBUse;

    hDC = BeginPaint(hWnd, &ps);
    lpInfo = (LPBITMAPINFOHEADER) GlobalLock(hDIBInfo);

    /* if using a palette for drawing and there is actually 
    ** a color table, then get a palette and realize it.
    */
    if (wPalOp && lpInfo->biClrUsed)
    {
	if (!hPalette)
	    hPalette = MakeDIBPalette(lpInfo);
	if (!hPalette)
	{
	    MessageBox(hWnd, "Can't create palette", "Error", MB_ICONSTOP | MB_OK);
	    goto ExitTime;
	}
	hOldPal = SelectPalette(hDC, hPalette, FALSE);
	RealizePalette(hDC);

	/* if using DIB_PAL_COLORS and the bitmap is not 24-bit,
	** then use a header with a color table of indices.
	*/
	if (wPalOp == IDM_PALIND && (lpInfo->biBitCount != 24))
	{
	    if (!hPalHeader)
	    {
		hPalHeader = MakeIndexHeader(lpInfo);
	    }
	    if (!hPalHeader)
	    {
		MessageBox(hWnd, "Can't create Indexed color table", "Error", MB_ICONSTOP | MB_OK);
		goto ExitTime;
	    }
	    lpHeader = (LPBITMAPINFOHEADER) GlobalLock(hPalHeader);
	    wDIBUse = DIB_PAL_COLORS;
	}
	else
	{
	    lpHeader = lpInfo;
	    wDIBUse = DIB_RGB_COLORS;
	}
    }
    else
    {
	lpHeader = lpInfo;
	wDIBUse = DIB_RGB_COLORS;
    }

    switch (wOperation)
    {
	case IDM_SETDIB:
		//error message if can't create
			
	    if (!hDDBitmap)
	    {
		hMemDC = CreateCompatibleDC(hDC);
		hDDBitmap = CreateCompatibleBitmap(hDC, 
				(WORD)lpInfo->biWidth, (WORD)lpInfo->biHeight);
		SetDIBits(hDC, hDDBitmap, 0, (WORD)lpInfo->biHeight, 
					(LPSTR)lpInfo + offBits, 
					(LPBITMAPINFO)lpHeader, wDIBUse);
		hOldBitmap = SelectObject(hMemDC, hDDBitmap);
	    }
	    BitBlt(hDC, 0, 0, (WORD)lpInfo->biWidth, (WORD)lpInfo->biHeight,
	    		hMemDC, 0, 0, SRCCOPY);
	    break;
	case IDM_TODEV:
	    SetDIBitsToDevice(hDC, 0, 0, (WORD)lpInfo->biWidth, (WORD)lpInfo->biHeight,
	    		0, 0, 0, (WORD)lpInfo->biHeight, 
			(LPSTR)lpInfo + offBits, (LPBITMAPINFO)lpHeader, wDIBUse);
	    break;
	case IDM_STRETCH:
	/* get dimensions of window and stretch to fit */
	    GetClientRect(hWnd, (LPRECT)&Rectangle);
	    StretchDIBits(hDC, 0, 0, Rectangle.right, Rectangle.bottom,
				0, 0, (WORD)lpInfo->biWidth, (WORD)lpInfo->biHeight,
				(LPSTR)lpInfo + offBits, 
				(LPBITMAPINFO)lpHeader, wDIBUse, SRCCOPY);

	/* NOTE: because driver does not do the StretchDIB
	**       itself, this is not a fast operation.
	**       internally it converts to CreateDIBitmap
	**       followed by a StretchBlt
	*/
	    break;
    }

    /* clean up any palette work */
    if (wPalOp)
    {
	SelectPalette(hDC, hOldPal, FALSE);
	if (wPalOp == IDM_PALIND)
	    GlobalUnlock(hPalHeader);
    }

ExitTime:
    GlobalUnlock(hDIBInfo);
    EndPaint(hWnd, &ps);
}


/****************************************************************************
 *									    *
 *  FUNCTION   : ReadDIB(hWnd)						    *
 *									    *
 *  PURPOSE    : Reads a DIB from a file, obtains a handle to it's          *
 *		 BITMAPINFO struct. and loads the DIB.                      *
 *									    *
 *  RETURNS    : TRUE  - DIB loads ok					    *
 *		 FALSE - otherwise					    *
 *									    *
 ****************************************************************************/
int ReadDIB(HWND hWnd)
{
    unsigned	       fh;
    LPBITMAPINFOHEADER lpbi;
    OFSTRUCT	       of;
    BITMAPFILEHEADER   bf;
    WORD		nNumColors;
    WORD		result = FALSE;		/* assume failure */

    /* Open the file and get a handle to it's BITMAPINFO */

    fh = OpenFile (achFileName, &of, OF_READ);
    if (fh == -1) {
        wsprintf(str,"Can't open file '%ls'", (LPSTR)achFileName);
	MessageBox(hWnd, str, "Error", MB_ICONSTOP | MB_OK);
	return (FALSE);
    }

    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIBInfo);

    /* read the BITMAPFILEHEADER */
    if (sizeof (bf) != _lread (fh, (LPSTR)&bf, sizeof (bf)))
	goto ErrExit;

    if (bf.bfType != 0x4d42)	/* 'BM' */
	goto ErrExit;

    if (sizeof(BITMAPINFOHEADER) != _lread (fh, (LPSTR)lpbi, sizeof(BITMAPINFOHEADER)))
	goto ErrExit;

    /* !!!!! for now, don't even deal with CORE headers */
    if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
	goto ErrExit;

    if (!(nNumColors = (WORD)lpbi->biClrUsed))
    {
	/* no color table for 24-bit, default size otherwise */
	if (lpbi->biBitCount != 24)
	    nNumColors = 1 << lpbi->biBitCount;	/* standard size table */
    }

    /*	fill in some default values if they are zero */
    if (lpbi->biClrUsed == 0)
        lpbi->biClrUsed = (DWORD)nNumColors;

    if (lpbi->biSizeImage == 0)
    {
	lpbi->biSizeImage = ((((lpbi->biWidth * (DWORD)lpbi->biBitCount) + 31) & ~31) >> 3)
			 * lpbi->biHeight;
    }

    /* get a proper-sized buffer for header, color table and bits */ 
    GlobalUnlock(hDIBInfo);
    hDIBInfo = GlobalReAlloc(hDIBInfo, lpbi->biSize +
    					nNumColors * sizeof(RGBQUAD) +
					lpbi->biSizeImage, 0);
    if (!hDIBInfo)	/* can't resize buffer for loading */
	goto ErrExit2;

    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIBInfo);

    /* read the color table */
    _lread (fh, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBQUAD));

    /* offset to the bits from start of DIB header */
    offBits = (WORD)lpbi->biSize + nNumColors * sizeof(RGBQUAD);

    if (bf.bfOffBits != 0L)
    {
        _llseek(fh,bf.bfOffBits,SEEK_SET);
    }
    if (lpbi->biSizeImage == lread(fh, (LPSTR)lpbi + offBits, lpbi->biSizeImage))
	result = TRUE;

ErrExit:
    _lclose(fh);
    GlobalUnlock(hDIBInfo);
ErrExit2:
    return(result);
}

/**************** PRIVATE ROUTINE TO READ MORE THAN 64K *********************/
/****************************************************************************
 *									    *
 *  FUNCTION   : lread(int fh, VOID FAR *pv, DWORD ul)			    *
 *									    *
 *  PURPOSE    : Reads data in steps of 32k till all the data has been read.*
 *									    *
 *  RETURNS    : 0 - If read did not proceed correctly. 		    *
 *		 number of bytes read otherwise.			    *
 *									    *
 ****************************************************************************/
DWORD PASCAL lread (int fh, VOID far *pv, DWORD ul)
{
    DWORD     ulT = ul;
//    BYTE huge *hp = pv;
	BYTE *hp = pv;

    while (ul > (DWORD)MAXREAD) {
	if (_lread(fh, (LPSTR)hp, (WORD)MAXREAD) != MAXREAD)
		return 0;
	ul -= MAXREAD;
	hp += MAXREAD;
    }
    if (_lread(fh, (LPSTR)hp, (WORD)ul) != (WORD)ul)
	return 0;
    return ulT;
}
/**************** PRIVATE ROUTINE TO READ MORE THAN 64K *********************/

/****************************************************************************
 *									    *
 *  FUNCTION   : InitDIB(hWnd)						    *
 *									    *
 *  PURPOSE    : cleans up old DIB info, reads new DIB from file,
 *		 resizes window for new DIB		 
 *									    *
 *  RETURNS    : TRUE  - DIB loads ok					    *
 *		 FALSE - otherwise					    *
 *									    *
 ****************************************************************************/
int InitDIB(HWND hWnd)
{
    LPBITMAPINFOHEADER lpbi;
    RECT		Rectangle;

    /* if there was an old DIB, free it up */
    if (bDIBLoaded)
    {
	if (hDDBitmap)
	{
	    SelectObject(hMemDC, hOldBitmap);
	    DeleteDC(hMemDC);
	    DeleteObject(hDDBitmap);
	    hDDBitmap = NULL;
	}
	bDIBLoaded = FALSE;
	if (hPalette)
	{
	    DeleteObject(hPalette);
	    hPalette = 0;
	}
	if (hPalHeader)
	{
	    GlobalFree(hPalHeader);
	    hPalHeader = NULL;
	}
    }


    /* load the DIB from the file */
    if (!ReadDIB(hWnd))
    {
	MessageBox(hWnd, "Error attempting to read DIB", "Error", MB_ICONSTOP | MB_OK);
	return(FALSE);
    }

    bDIBLoaded = TRUE;		/* there is a DIB loaded now */

    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIBInfo);
    SetWindowText(hWnd, achFileName);
    Rectangle.left	 = 0;
    Rectangle.top	 = 0;
    Rectangle.right  = (WORD)lpbi->biWidth;
    Rectangle.bottom = (WORD)lpbi->biHeight;
    GlobalUnlock(hDIBInfo);

    /* Compute the size of the window rectangle based on the given
     * client rectangle size and the window style, then size the
     * window.  Do not deal with possibility of more than one menu line.
     */
    AdjustWindowRect (&Rectangle, WS_OVERLAPPEDWINDOW, TRUE);
    SetWindowPos (hWnd, (HWND)NULL, 0, 0,
		      Rectangle.right  - Rectangle.left,
		      Rectangle.bottom - Rectangle.top + 1,
		      SWP_NOMOVE | SWP_NOZORDER);

    GetClientRect(hWnd, &Rectangle);

    return(TRUE);
}

/****************************************************************************

    FUNCTION: About(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages for "About" dialog box

    MESSAGES:

	WM_INITDIALOG - initialize dialog box
	WM_COMMAND    - Input received

    COMMENTS:

	No initialization is needed for this particular dialog box, but TRUE
	must be returned to Windows.

	Wait for user to click on "Ok" button, then close the dialog box.

****************************************************************************/

//BOOL FAR PASCAL __export About(hDlg, message, wParam, lParam)
BOOL APIENTRY About(hDlg, message, wParam, lParam)
HWND hDlg;                                /* window handle of the dialog box */
unsigned message;                         /* type of message                 */
WORD wParam;                              /* message-specific information    */
LONG lParam;
{
    switch (message) {
	case WM_INITDIALOG:		   /* message: initialize dialog box */
	    return (TRUE);

	case WM_COMMAND:		      /* message: received a command */
	    if (wParam == IDOK                /* "OK" box selected?	     */
                || wParam == IDCANCEL) {      /* System menu close command? */
		EndDialog(hDlg, TRUE);	      /* Exits the dialog box	     */
		return (TRUE);
	    }
	    break;
    }
    return (FALSE);			      /* Didn't process a message    */
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -