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

📄 dib.c

📁 WinCVS 源码,流行的CVS客户端源码程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/*************************************************************************
/* This is a 'best of' choice of DIB functions taken from Microsoft
/* examples files (examples wincap32 : file.c, dibutil.c ...)
/*************************************************************************/

#include <windows.h>
#include <windowsx.h>
#include "dib.h"


/****************************************************************************
 *                                                                          *
 *  FUNCTION   : DibNumColors(VOID FAR * pv)                                *
 *                                                                          *
 *  PURPOSE    : Determines the number of colors in the DIB by looking at   *
 *               the BitCount filed in the info block.                      *
 *                                                                          *
 *  RETURNS    : The number of colors in the DIB.                           *
 *               if bitmap is in 8 bit mode but use only 4 colors           *
 *               function can return 4 (number of color really used)        *
 *               Use DibGetPaletteSize instead...                           *
 *                                                                          *
 ****************************************************************************/
WORD DibNumColors (VOID FAR * pv)
{
    INT                 bits;
    LPBITMAPINFOHEADER  lpbi;
    LPBITMAPCOREHEADER  lpbc;

    lpbi = ((LPBITMAPINFOHEADER)pv);
    lpbc = ((LPBITMAPCOREHEADER)pv);

    /*  With the BITMAPINFO format headers, the size of the palette
     *  is in biClrUsed, whereas in the BITMAPCORE - style headers, it
     *  is dependent on the bits per pixel ( = 2 raised to the power of
     *  bits/pixel).
     */
    if (lpbi->biSize != sizeof(BITMAPCOREHEADER)){
        if (lpbi->biClrUsed != 0)
            return (WORD)lpbi->biClrUsed;
        bits = lpbi->biBitCount;
    }
    else
        bits = lpbc->bcBitCount;

    switch (bits){
        case 1:
                return 2;
        case 4:
                return 16;
        case 8:
                return 256;
        default:
                /* A 24 bitcount DIB has no color table */
                return 0;
    }
}

/****************************************************************************
 *                                                                          *
 *  FUNCTION   : DibGetPaletteSize(VOID FAR * pv)                           *
 *                                                                          *
 *  PURPOSE    : Return the bitmap encoding type (8 bit, 24 bit...          *
 *               the BitCount filed in the info block.                      *
 *                                                                          *
 *  RETURNS    : the encoding type of the bitmap.                           *
 *                                                                          *
 ****************************************************************************/
WORD DibGetPaletteSize (VOID FAR * pv)
{
    INT                 bits;
    LPBITMAPINFOHEADER  lpbi;
    LPBITMAPCOREHEADER  lpbc;

    lpbi = ((LPBITMAPINFOHEADER)pv);
    lpbc = ((LPBITMAPCOREHEADER)pv);

    /*  With the BITMAPINFO format headers, the size of the palette
     *  is in biClrUsed, whereas in the BITMAPCORE - style headers, it
     *  is dependent on the bits per pixel ( = 2 raised to the power of
     *  bits/pixel).
     */
    if (lpbi->biSize != sizeof(BITMAPCOREHEADER))
        bits = lpbi->biBitCount;
    else
        bits = lpbc->bcBitCount;
	
	return bits;
}

/****************************************************************************
 *                                                                          *
 *  FUNCTION   :  DibCopyPalette(HBITMAP src, HBITMAP dst)                  *
 *                                                                          *
 *  PURPOSE    :  Copy the palette from src to dst if possible              *                                                                          *
 *                                                                          *
 ****************************************************************************/
VOID
DibCopyPalette(HBITMAP dst, HBITMAP src)
{
	LPBITMAPINFO src_header, dst_header;
	RGBQUAD *src_rgb, *dst_rgb;
	WORD colorMode;

	src_header = (LPBITMAPINFO) GlobalLock((HGLOBAL)src);
	dst_header = (LPBITMAPINFO) GlobalLock((HGLOBAL)dst);

	src_rgb = (RGBQUAD FAR *)((LPSTR)src_header + (WORD)src_header->bmiHeader.biSize);
	dst_rgb = (RGBQUAD FAR *)((LPSTR)dst_header + (WORD)dst_header->bmiHeader.biSize);

	colorMode = DibGetPaletteSize(src_header);
	switch(colorMode)
	{
		case 4:
		case 8:
			memcpy(dst_rgb, src_rgb,PaletteSize(&src_header->bmiHeader));
			break;
	}

	GlobalUnlock((HGLOBAL)src);
	GlobalUnlock((HGLOBAL)dst);
}

/****************************************************************************
 *                                                                          *
 *  FUNCTION   :  PaletteSize(VOID FAR * pv)                                *
 *                                                                          *
 *  PURPOSE    :  Calculates the palette size in bytes. If the info. block  *
 *                is of the BITMAPCOREHEADER type, the number of colors is  *
 *                multiplied by 3 to give the palette size, otherwise the   *
 *                number of colors is multiplied by 4.                                                          *
 *                                                                          *
 *  RETURNS    :  Palette size in number of bytes.                          *
 *                                                                          *
 ****************************************************************************/
WORD PaletteSize (VOID FAR * pv)
{
    LPBITMAPINFOHEADER lpbi;
    WORD               NumColors;

    lpbi      = (LPBITMAPINFOHEADER)pv;
    NumColors = DibNumColors(lpbi);

    if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
        return (WORD)(NumColors * sizeof(RGBTRIPLE));
    else
        return (WORD)(NumColors * sizeof(RGBQUAD));
}

/****************************************************************************
 *                                                                          *
 *  FUNCTION   : WriteMapFileHeaderandConvertFromDwordAlignToPacked(HFILE fh, LPBITMAPFILEHEADER pbf)
 *                                                                          *
 *  PURPOSE    : write header structure (which NOT packed) and write it PACKED
 *                                                                          *
 *  RETURNS    : VOID
 *                                                                          *
 ****************************************************************************/

VOID WriteMapFileHeaderandConvertFromDwordAlignToPacked(HFILE fh, LPBITMAPFILEHEADER pbf)
{

        /* write bfType*/
    _lwrite(fh, (LPSTR)&pbf->bfType, (UINT)sizeof (WORD));
        /* now pass over extra word, and only write next 3 DWORDS!*/
        _lwrite(fh, (LPSTR)&pbf->bfSize, sizeof(DWORD) * 3);
}

/*************************************************************************
 *
 * CreateDIB()
 *
 * Parameters:
 *
 * DWORD dwWidth    - Width for new bitmap, in pixels
 * DWORD dwHeight   - Height for new bitmap 
 * WORD  wBitCount  - Bit Count for new DIB (1, 4, 8, or 24)
 *
 * Return Value:
 *
 * HDIB             - Handle to new DIB
 *
 * Description:
 *
 * This function allocates memory for and initializes a new DIB by
 * filling in the BITMAPINFOHEADER, allocating memory for the color
 * table, and allocating memory for the bitmap bits.  As with all
 * HDIBs, the header, colortable and bits are all in one contiguous
 * memory block.  This function is similar to the CreateBitmap() 
 * Windows API.
 *
 * The colortable and bitmap bits are left uninitialized (zeroed) in the
 * returned HDIB.
 *
 *
 * History:   Date      Author              Reason
 *            3/20/92   Mark Bader          Created
 *
 ************************************************************************/

HBITMAP CreateDIB(DWORD dwWidth, DWORD dwHeight, WORD wBitCount, HPALETTE hPal)
{
    BITMAPINFOHEADER    bi;             /*  bitmap header */
    LPBITMAPINFOHEADER  lpbi;           /*  pointer to BITMAPINFOHEADER */
    DWORD               dwLen;          /*  size of memory block */
    HBITMAP             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 = 0;           /*  0's here mean "default" */
    bi.biXPelsPerMeter = 0;
    bi.biYPelsPerMeter = 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 = WIDTHBYTES(wBitCount * dwWidth);
    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 = (LPBITMAPINFOHEADER)GlobalLock(hDIB);

    /*  use our bitmap info structure to fill in first part of */
    /*  our DIB with the BITMAPINFOHEADER */

    *lpbi = bi;

	/*
	 * Copy the palette in the new created image
	 */
	if (wBitCount == 8)
	{
		PALETTEENTRY pal[256];
		RGBQUAD *pRgb;
		int i;

	 	GetPaletteEntries(hPal, 0, 256, pal);

		pRgb = (RGBQUAD FAR *)((LPSTR)lpbi + (WORD)lpbi->biSize);

		/* Fill in the palette entries from the DIB color table and
		 * create a logical color palette.
		 */
		for (i = 0; i < 256; i++)
		{
			pRgb[i].rgbRed = pal[i].peRed;
			pRgb[i].rgbGreen = pal[i].peGreen;
			pRgb[i].rgbBlue = pal[i].peBlue;
		}
	}

    // 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;
}

/*************************************************************************
 *
 * Function:  ReadDIBFile (int)
 *
 *  Purpose:  Reads in the specified DIB file into a global chunk of
 *            memory.
 *
 *  Returns:  A handle to a dib (hDIB) if successful.
 *            NULL if an error occurs.
 *
 * Comments:  BITMAPFILEHEADER is stripped off of the DIB.  Everything
 *            from the end of the BITMAPFILEHEADER structure on is
 *            returned in the global memory handle.
 *
 *
 * NOTE: The DIB API were not written to handle OS/2 DIBs, so this
 * function will reject any file that is not a Windows DIB.
 *
 * History:   Date      Author       Reason
 *            9/15/91   Mark Bader   Based on DIBVIEW
 *            6/25/92   Mark Bader   Added check for OS/2 DIB
 *            7/21/92   Mark Bader   Added code to deal with bfOffBits
 *                                     field in BITMAPFILEHEADER      
 *            9/11/92   Mark Bader   Fixed Realloc Code to free original mem
 *            1/25/94   Hung Nguyen  Changed file APIs to Win32 APIs
 *
 *************************************************************************/

HANDLE ReadDIBFile(HANDLE hFile)
{
    BITMAPFILEHEADER    bmfHeader;
    DWORD               dwBitsSize;
    UINT                nNumColors;   /*  Number of colors in table */
    HANDLE              hDIB;        
    HANDLE              hDIBtmp;      /*  Used for GlobalRealloc() //MPB */
    LPBITMAPINFOHEADER  lpbi;
    DWORD               offBits;
    DWORD               dwRead;

    /*  get length of DIB in bytes for use when reading */

    dwBitsSize = GetFileSize(hFile, NULL);

    /*  Allocate memory for header & color table. We'll enlarge this */
    /*  memory as needed. */

    hDIB = GlobalAlloc(GMEM_MOVEABLE, (DWORD)(sizeof(BITMAPINFOHEADER) +
            256 * sizeof(RGBQUAD)));

    if (!hDIB)
        return NULL;

    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);

    if (!lpbi) 
    {
        GlobalFree(hDIB);
        return NULL;
    }

    /*  read the BITMAPFILEHEADER from our file */

    if (!ReadFile(hFile, (LPSTR)&bmfHeader, sizeof (BITMAPFILEHEADER),
            &dwRead, NULL))
        goto ErrExit;

    if (sizeof (BITMAPFILEHEADER) != dwRead)
        goto ErrExit;

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

    /*  read the BITMAPINFOHEADER */

    if (!ReadFile(hFile, (LPSTR)lpbi, sizeof(BITMAPINFOHEADER), &dwRead,
            NULL))
        goto ErrExit;

    if (sizeof(BITMAPINFOHEADER) != dwRead)
        goto ErrExit;

    /*  Check to see that it's a Windows DIB -- an OS/2 DIB would cause */
    /*  strange problems with the rest of the DIB API since the fields */
    /*  in the header are different and the color table entries are */
    /*  smaller. */
    /*  */
    /*  If it's not a Windows DIB (e.g. if biSize is wrong), return NULL. */

    if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
        goto ErrExit;

    /*  Now determine the size of the color table and read it.  Since the */
    /*  bitmap bits are offset in the file by bfOffBits, we need to do some */
    /*  special processing here to make sure the bits directly follow */
    /*  the color table (because that's the format we are susposed to pass */
    /*  back) */

    if (!(nNumColors = (UINT)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 = nNumColors;

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

⌨️ 快捷键说明

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