📄 dibutils.cpp
字号:
/**************************************************************************
UTILS.C - useful functions for WinG Sample Apps
**************************************************************************/
/**************************************************************************
(C) Copyright 1994 Microsoft Corp. All rights reserved.
You have a royalty-free right to use, modify, reproduce and
distribute the Sample Files (and/or any modified version) in
any way you find useful, provided that you agree that
Microsoft has no warranty obligations or liability for any
Sample Application Files which are modified.
**************************************************************************/
/*----------------------------------------------------------------------------*\
| Functions for handling Device Independent Bitmaps and clearing the |
| System Palette. |
\*----------------------------------------------------------------------------*/
#include "stdafx.h"
#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include "dibutils.h"
#if defined(WIN32) || defined(_WIN32)
#include <memory.h> // for _fmemcpy()
#define _huge
#ifndef hmemcpy
#define hmemcpy memcpy
#endif
#endif
#define BFT_ICON 0x4349 /* 'IC' */
#define BFT_BITMAP 0x4d42 /* 'BM' */
#define BFT_CURSOR 0x5450 /* 'PT' */
/* flags for _lseek */
#define SEEK_CUR 1
#define SEEK_END 2
#define SEEK_SET 0
/*
* Clear the System Palette so that we can ensure an identity palette
* mapping for fast performance.
*/
void ClearSystemPalette(void)
{
//*** A dummy palette setup
struct
{
WORD Version;
WORD NumberOfEntries;
PALETTEENTRY aEntries[256];
} Palette =
{
0x300,
256
};
HPALETTE ScreenPalette = 0;
HDC ScreenDC;
int Counter;
UINT nMapped = 0;
BOOL bOK = FALSE;
int nOK = 0;
//*** Reset everything in the system palette to black
for(Counter = 0; Counter < 256; Counter++)
{
Palette.aEntries[Counter].peRed = 0;
Palette.aEntries[Counter].peGreen = 0;
Palette.aEntries[Counter].peBlue = 0;
Palette.aEntries[Counter].peFlags = PC_NOCOLLAPSE;
}
//*** Create, select, realize, deselect, and delete the palette
ScreenDC = GetDC(NULL);
ScreenPalette = CreatePalette((LOGPALETTE *)&Palette);
if (ScreenPalette)
{
ScreenPalette = SelectPalette(ScreenDC,ScreenPalette,FALSE);
nMapped = RealizePalette(ScreenDC);
ScreenPalette = SelectPalette(ScreenDC,ScreenPalette,FALSE);
bOK = DeleteObject(ScreenPalette);
}
nOK = ReleaseDC(NULL, ScreenDC);
return;
}
/*
* Open a DIB file and return a MEMORY DIB, a memory handle containing..
*
* BITMAP INFO bi
* palette data
* bits....
*/
int DibWriteFile(LPSTR szFile, LPBITMAPINFOHEADER lpbi)
{
HFILE fh;
OFSTRUCT of;
fh = OpenFile(szFile, &of, OF_WRITE | OF_CREATE);
if (!fh) {
// printf("la regamos0");
return 0;
}
long size = DibSize(lpbi);
// write file header
BITMAPFILEHEADER bmf;
bmf.bfType = 'BM';
bmf.bfSize = sizeof(bmf) + size;
bmf.bfReserved1 = 0;
bmf.bfReserved2 = 0;
bmf.bfOffBits = sizeof(bmf) + (char far*)(DibPtr(lpbi)) - (char far*)lpbi;
#if defined( __WATCOMC__) || defined(_MSC_VER)
if (_hwrite(fh, (LPCSTR)(&bmf), sizeof(bmf))<0 ||
_hwrite(fh, (LPCSTR)lpbi, size)<0) {
_lclose(fh);
// printf("la regamos1");
return 0;
}
#else
if (_hwrite(fh, (LPBYTE)(&bmf), sizeof(bmf))<0 ||
_hwrite(fh, (LPBYTE)lpbi, size)<0) {
_lclose(fh);
// printf("la regamos1");
return 0;
}
#endif
_lclose(fh);
return 1;
}
// The following is an alternative implementation of DIB writing, since
// the above doesn't appear to work.
/****************************************************************************
* *
* 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 NumColors * sizeof(RGBTRIPLE);
else
return NumColors * sizeof(RGBQUAD);
}
/****************************************************************************
* *
* FUNCTION : lwrite(int fh, VOID FAR *pv, DWORD ul) *
* *
* PURPOSE : Writes data in steps of 32k till all the data is written. *
* *
* RETURNS : 0 - If write did not proceed correctly. *
* number of bytes written otherwise. *
* *
****************************************************************************/
#define MAXREAD 32768 /* Number of bytes to be read during */
/* each read operation. */
DWORD PASCAL lwrite(int fh, VOID FAR *pv, DWORD ul)
{
DWORD ulT = ul;
#if defined(WINNT) || defined(WIN32) || defined(__WIN32__)
BYTE *hp = (BYTE *) pv;
#else
BYTE huge *hp = (BYTE huge *) pv;
#endif
while (ul > MAXREAD) {
if (_lwrite(fh, (LPSTR) hp, (WORD) MAXREAD) != MAXREAD)
return 0;
ul -= MAXREAD;
hp += MAXREAD;
}
if (_lwrite(fh, (LPSTR) hp, (WORD) ul) != (WORD) ul)
return 0;
return ulT;
}
/****************************************************************************
* *
* FUNCTION : WriteDIB(LPSTR szFile,HANDLE hdib) *
* *
* PURPOSE : Write a global handle in CF_DIB format to a file. *
* *
* RETURNS : TRUE - if successful. *
* FALSE - otherwise *
* *
****************************************************************************/
BOOL WriteDIB(const char *szFile, LPBITMAPINFOHEADER lpbi)
{
BITMAPFILEHEADER hdr;
int fh;
OFSTRUCT of;
if (!lpbi)
return FALSE;
fh = OpenFile(szFile, &of, OF_CREATE | OF_READWRITE);
if (fh == -1)
return FALSE;
/* Fill in the fields of the file header */
hdr.bfType = BFT_BITMAP;
hdr.bfSize = DibSize(lpbi) + sizeof(BITMAPFILEHEADER);
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + lpbi->biSize +
PaletteSize(lpbi);
/* Write the file header */
_lwrite(fh, (LPSTR) &hdr, sizeof(BITMAPFILEHEADER));
/* Write the DIB header and the bits */
lwrite(fh, (LPSTR) lpbi, DibSize(lpbi));
_lclose(fh);
return TRUE;
}
PDIB DibOpenFile(LPSTR szFile)
{
HFILE fh;
DWORD dwLen;
DWORD dwBits;
PDIB pdib;
LPVOID p;
OFSTRUCT of;
#if defined(WIN32) || defined(_WIN32)
#define GetCurrentInstance() GetModuleHandle(NULL)
#else
#define GetCurrentInstance() (HINSTANCE)SELECTOROF((LPVOID)&of)
#endif
fh = OpenFile(szFile, &of, OF_READ);
#if 0
if (fh == -1)
{
HRSRC h;
h = FindResource(GetCurrentInstance(), szFile, RT_BITMAP);
#if defined(WIN32) || defined(_WIN32)
//!!! can we call GlobalFree() on this? is it the right format.
//!!! can we write to this resource?
if (h)
return (PDIB)LockResource(LoadResource(GetCurrentInstance(), h));
#else
if (h)
fh = AccessResource(GetCurrentInstance(), h);
#endif
}
#endif
if (fh == -1)
return NULL;
pdib = DibReadBitmapInfo(fh);
if (!pdib)
return NULL;
/* How much memory do we need to hold the DIB */
dwBits = pdib->biSizeImage;
dwLen = pdib->biSize + DibPaletteSize(pdib) + dwBits;
/* Can we get more memory? */
p = GlobalReAllocPtr(pdib,dwLen,0);
if (!p)
{
GlobalFreePtr(pdib);
pdib = NULL;
}
else
{
pdib = (PDIB)p;
}
if (pdib)
{
/* read in the bits */
_hread(fh, (LPBYTE)pdib + (UINT)pdib->biSize + DibPaletteSize(pdib), dwBits);
}
_lclose(fh);
return pdib;
}
/*
* ReadDibBitmapInfo()
*
* Will read a file in DIB format and return a global HANDLE to its
* BITMAPINFO. This function will work with both "old" and "new"
* bitmap formats, but will always return a "new" BITMAPINFO.
*/
PDIB DibReadBitmapInfo(HFILE fh)
{
DWORD off;
HANDLE hbi = NULL;
int size;
int i;
int nNumColors;
RGBQUAD FAR *pRgb;
BITMAPINFOHEADER bi;
BITMAPCOREHEADER bc;
BITMAPFILEHEADER bf;
PDIB pdib;
if (fh == -1)
return NULL;
off = _llseek(fh,0L,SEEK_CUR);
if (sizeof(bf) != _lread(fh,(LPSTR)&bf,sizeof(bf)))
return FALSE;
/*
* do we have a RC HEADER?
*/
if (bf.bfType != BFT_BITMAP)
{
bf.bfOffBits = 0L;
_llseek(fh,off,SEEK_SET);
}
if (sizeof(bi) != _lread(fh,(LPSTR)&bi,sizeof(bi)))
return FALSE;
/*
* what type of bitmap info is this?
*/
switch (size = (int)bi.biSize)
{
default:
case sizeof(BITMAPINFOHEADER):
break;
case sizeof(BITMAPCOREHEADER):
bc = *(BITMAPCOREHEADER*)&bi;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = (DWORD)bc.bcWidth;
bi.biHeight = (DWORD)bc.bcHeight;
bi.biPlanes = (UINT)bc.bcPlanes;
bi.biBitCount = (UINT)bc.bcBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
_llseek(fh,(LONG)sizeof(BITMAPCOREHEADER)-sizeof(BITMAPINFOHEADER),SEEK_CUR);
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -