📄 dibapi.cpp
字号:
*
* Return Value:
*
* A handle to DIB data buffer, or null if unsuccessful
*
* Description:
*
* This function reads in the DIB file into a global chuck
* of memory.
*
************************************************************/
HDIB ReadDIBFile(HANDLE hFile)
{
BITMAPFILEHEADER bmfHeader;
DWORD dwBitsSize;
UINT nNumColors;//number of colors in table
HDIB hDIB;
HDIB hDIBtmp;// used for global realloc()
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,
(LPBYTE) &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,
(LPBYTE)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 file in the header are different and the color
//table entried are smaller
// if it is not a window DIB, 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 bfoggbits,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 ;//stardard 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 ;
}
//get the proper sized buffer for header,color table and bits
GlobalUnlock(hDIB);
hDIBtmp=GlobalReAlloc(hDIB,lpbi->biSize +nNumColors*
sizeof(RGBQUAD)+lpbi->biSizeImage ,0);
if(!hDIBtmp)//can't resize buffer for loading
goto ErrExitUnlock;
else
hDIB=hDIBtmp;
lpbi=(LPBITMAPINFOHEADER)GlobalLock(hDIB);
//read the color table
ReadFile(hFile,(LPBYTE)(lpbi)+lpbi->biSize,
nNumColors*sizeof(RGBQUAD),&dwRead,NULL);
//offset to the bits from start of DIB header
offBits=lpbi->biSize +nNumColors*sizeof(RGBQUAD);
//If the bfOffBits field is none zero, then the bits might not
// be directly following the color table in the file,Use the value
//in bfOffBits to seek the bits
if(bmfHeader.bfOffBits !=0L)
SetFilePointer(hFile,bmfHeader.bfOffBits ,NULL,FILE_BEGIN);
if(ReadFile(hFile,(LPBYTE)lpbi+offBits,lpbi->biSizeImage,
&dwRead,NULL))
goto OKExit;
ErrExit:
GlobalUnlock(hDIB);
ErrExitUnlock:
GlobalFree(hDIB);
return NULL;
OKExit:
GlobalUnlock(hDIB);
return hDIB;
}
/************************************************************
*
* Function Name:
*
* SaveDIB()
*
* Parameters :
*
* HANDLE hDIB: -handle of the DIB to save
* LPTSTR lpFileName:-specifies the file to save the DIB to
*
* Return Value:
*
* TRUE if successful, or FALSE if unsuccessful
*
* Description:
*
* This function Save the specified DIB into a bitmap File
* name on disk
*
************************************************************/
BOOL SaveDIB(HDIB hDib, LPCTSTR lpFileName)
{
BITMAPFILEHEADER bmfHdr;//Header for Bitmap FIle
LPBITMAPINFOHEADER lpBI;//pointer to DIB infor structure
HANDLE fh;//file handle for opened file
DWORD dwDIBSize;
DWORD dwWritten;
if(!hDib)
return FALSE;
fh=CreateFile(lpFileName,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL|
FILE_FLAG_SEQUENTIAL_SCAN,
NULL);
if(fh==INVALID_HANDLE_VALUE)
return FALSE;
//Get a pointer to the DIB memory, the first of which contails
// a BITMAPINFO structure
lpBI=(LPBITMAPINFOHEADER)GlobalLock(hDib);
if(!lpBI)
{
GlobalUnlock(hDib);
CloseHandle(fh);
return FALSE;
}
//check to see if we'are dealing with an OS/2 DIB. if so,
//don't save it because our functions aren't written to
//deal with this DIBs
if(lpBI->biSize !=sizeof(BITMAPINFOHEADER))
{
GlobalUnlock(hDib);
CloseHandle(fh);
return FALSE;
}
//Fill in the fields of the file header
//Fill in the file type (first 2bytes must be "BM" for
//a Bitmap
bmfHdr.bfType =DIB_HEADER_MARKER;//"BM"
//calculating the size of the DIB is a bit trickly(if we want to
// do it right).The easiest way to do this is to call GlobalSize()
// on our global handle, but since the size of our global memory
//may have been padded a few bytes, we may end uup writing out a
//few too many bytes to the file(which may vause problems with
//some apps,like HC 3.0
// so Instead let's calculate the size manually
//To do this ,find size of Header Plus size of Color table,Since
//the first DWORD in both BITMAPINFOHEADER and
//BITMAPCOREHEADER contains the size of the structure, let's use
//this
//partial calculation
dwDIBSize=*(LPDWORD)lpBI+
DIBNumColors((LPBYTE)lpBI)*sizeof(RGBQUAD);
//Now calculate the size of the image
//It's an RLE butmap,we can't calculate size, so trust the
//biSizeImage field
if((lpBI->biCompression ==BI_RLE8)||
(lpBI->biCompression ==BI_RLE4))
dwDIBSize+=lpBI->biSizeImage ;
else
{
DWORD dwBmBitsSize;//Size of Bitmap Bits only
//It's not RLE,so size is width (DWORD aligned)*Height
dwBmBitsSize=WIDTHBYTES((lpBI->biWidth )*
((DWORD)lpBI->biBitCount ))*lpBI->biHeight ;
dwDIBSize+=dwBmBitsSize;
//Now since we have calculated the correct size,why don't
// fill in the biSizeImage field
lpBI->biSizeImage =dwBmBitsSize;
}
//calculate the file size by adding the DIB size to
//size of (BITMAPFILEHEADER)
bmfHdr.bfSize =dwDIBSize+sizeof(BITMAPFILEHEADER);
bmfHdr.bfReserved1= 0;
bmfHdr.bfReserved2 =0;
//Now calculate the offset the actual bitmap bits will be in
// the file-- It's tje bitmap file header plus the DIB header
// plus the size of the color table
bmfHdr.bfOffBits =(DWORD)sizeof(BITMAPFILEHEADER)+
lpBI->biSize +DIBNumColors((LPBYTE)lpBI)*sizeof(RGBQUAD);
//write the file header
WriteFile(fh,(LPBYTE)&bmfHdr,
sizeof(BITMAPFILEHEADER),
&dwWritten,NULL);
//write the DIB header and the bits--use local version of
//mywrite, so we can write more than 32767 bytes of data
WriteFile(fh,(LPBYTE)lpBI,dwDIBSize,&dwWritten,NULL);
GlobalUnlock(hDib);
CloseHandle(fh);
if(dwWritten==0)
return FALSE;//oops, something happend in the write
else
return TRUE;//success code
}
/************************************************************
*
* Function Name:
*
* BytesPerLine()
*
* Parameters :
*
* LPBYTE lpDIB: -pointer to packed -DIB memory block
*
* Return Value:
*
* DWORD -number of bytes in one scan line
*
* Description:
*
* This function calculates the number of bytes in one
* scan line
*
************************************************************/
DWORD BytesPerLine(LPBYTE lpDIB)
{
//计算每行需要的字节数
return WIDTHBYTES(((LPBITMAPINFOHEADER)lpDIB)->biWidth *
((LPBITMAPINFOHEADER)lpDIB)->biPlanes *
((LPBITMAPINFOHEADER)lpDIB)->biBitCount );
}
/************************************************************
*
* Function Name:
*
* BytesPerLine()
*
* Parameters :
*
* HANDLE hDIB: -handle of the DIB
*
* Return Value:
*
* DWORD -number of bytes in one scan line
*
* Description:
*
* This function calculates the number of bytes in one
* scan line
*
************************************************************/
DWORD BytesPerLine(HDIB hDIB)
{
LPBITMAPINFOHEADER lpDIB;
lpDIB=(LPBITMAPINFOHEADER)GlobalLock(hDIB);
DWORD dwBytes= WIDTHBYTES(((LPBITMAPINFOHEADER)lpDIB)->biWidth *
((LPBITMAPINFOHEADER)lpDIB)->biPlanes *
((LPBITMAPINFOHEADER)lpDIB)->biBitCount );
GlobalUnlock(hDIB);
return dwBytes;
}
/************************************************************
*
* Function Name:
*
* DIBLockSize()
*
* Parameters :
*
* LPBYTE lpDIB: -pointer to packed -DIB memory block
*
* Return Value:
*
* DWORD -DIB block size
*
* Description:
*
* This function calculates the block size of image bit
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -