📄 dibapi.cpp
字号:
//**********************************************************************
//
// AIBAPI.CPP
//
// Source file for Device-Independent Bitmap (DIB) API.
//
//**********************************************************************
#define STRICT // enable strict type checking
#include "stdafx.h"
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <io.h>
#include <direct.h>
#include <stdlib.h>
#include <assert.h>
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include "dibapi.h"
#include "KLTransformDoc.h"
#include "KLTransformView.h"
/*****************************************************************
*
* LoadDIB()
*
* Loads the specified DIB from a file, allocates memory for it,
* and reads the disk file into the memory.
*
*
* Parameters:
*
* LPCTSTR lpFileName - specifies the file to load a DIB from
*
* Returns: A handle to a DIB, or NULL if unsuccessful.
*
* NOTE: The DIB API were not written to handle OS/2 DIBs; This
* function will reject any file that is not a Windows DIB.
*
*************************************************************************/
HDIB LoadDIB(LPCTSTR lpFileName)
{
HDIB hDIB;
HANDLE hFile;
// Set the cursor to a hourglass, in case the loading operation
// takes more than a sec, the user will know what's going on.
SetCursor(LoadCursor(NULL, IDC_WAIT));
if ((hFile = CreateFile(lpFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
NULL)) != INVALID_HANDLE_VALUE)
{
hDIB = ReadDIBFile(hFile);
CloseHandle(hFile);
SetCursor(LoadCursor(NULL, IDC_ARROW));
return hDIB;
}
else
{
SetCursor(LoadCursor(NULL, IDC_ARROW));
return NULL;
}
}
/*************************************************************************
*
* 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.
*
*************************************************************************/
HDIB 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, (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 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;
}
// get a 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 ErrExitNoUnlock; //MPB
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 non-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);
ErrExitNoUnlock:
GlobalFree(hDIB);
return NULL;
OKExit:
GlobalUnlock(hDIB);
return hDIB;
}
/*************************************************************************
*
* CreateDIBPalette()
*
* Parameter:
*
* LPBYTE lpbi - specifies the DIB
*
* Return Value:
*
* HPALETTE - specifies the palette
*
* Description:
*
* This function creates a palette from a DIB by allocating memory for the
* logical palette, reading and storing the colors from the DIB's color table
* into the logical palette, creating a palette from this logical palette,
* and then returning the palette's handle. This allows the DIB to be
* displayed using the best possible colors (important for DIBs with 256 or
* more colors).
*
************************************************************************/
HPALETTE CreateDIBPalette(LPBYTE lpbi)
{
LPLOGPALETTE lpPal; // pointer to a logical palette
HANDLE hLogPal; // handle to a logical palette
HPALETTE hPal = NULL; // handle to a palette
int i, wNumColors; // loop index, number of colors in color table
LPBITMAPINFO lpbmi; // pointer to BITMAPINFO structure (Win3.0)
LPBITMAPCOREINFO lpbmc; // pointer to BITMAPCOREINFO structure (OS/2)
BOOL bWinStyleDIB; // Win3.0 DIB?
// if handle to DIB is invalid, return NULL
if (! lpbi)
return NULL;
// get pointer to BITMAPINFO (Win 3.0)
lpbmi = (LPBITMAPINFO)lpbi;
// get pointer to BITMAPCOREINFO (OS/2 1.x)
lpbmc = (LPBITMAPCOREINFO)lpbi;
// get the number of colors in the DIB
wNumColors = DIBNumColors(lpbi);
// is this a Win 3.0 DIB?
bWinStyleDIB = IS_WIN30_DIB(lpbi);
if (wNumColors)
{
// allocate memory block for logical palette
hLogPal = GlobalAlloc(GHND, sizeof(LOGPALETTE) +
sizeof(PALETTEENTRY) * wNumColors);
// if not enough memory, clean up and return NULL
if (!hLogPal)
return NULL;
// lock memory block and get pointer to it
lpPal = (LPLOGPALETTE)GlobalLock(hLogPal);
// set version and number of palette entries
lpPal->palVersion = PALVERSION;
lpPal->palNumEntries = wNumColors;
// store RGB triples (if Win 3.0 DIB) or RGB quads (if OS/2 DIB)
// into palette
for (i = 0; i < wNumColors; i++)
{
if (bWinStyleDIB)
{
lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed;
lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue;
lpPal->palPalEntry[i].peFlags = 0;
}
else
{
lpPal->palPalEntry[i].peRed = lpbmc->bmciColors[i].rgbtRed;
lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen;
lpPal->palPalEntry[i].peBlue = lpbmc->bmciColors[i].rgbtBlue;
lpPal->palPalEntry[i].peFlags = 0;
}
}
// create the palette and get handle to it
hPal = CreatePalette(lpPal);
// if error getting handle to palette, clean up and return NULL
if (!hPal)
{
GlobalUnlock(hLogPal);
GlobalFree(hLogPal);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -