📄 dib.cpp
字号:
//DEL {
//DEL // allocate memory block for logical palette
//DEL hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE)
//DEL + sizeof(PALETTEENTRY) * wNumColors);
//DEL // if not enough memory, clean up and return NULL
//DEL if (hLogPal == 0)
//DEL {
//DEL ::GlobalUnlock((HGLOBAL)m_hDIB);
//DEL return FALSE;
//DEL }
//DEL m_lpPal = (LPLOGPALETTE) ::GlobalLock((HGLOBAL) hLogPal);
//DEL // set version and number of palette entries
//DEL m_lpPal->palVersion = PALVERSION;
//DEL m_lpPal->palNumEntries = (WORD)wNumColors;
//DEL // is this a Win 3.0 DIB?
//DEL bWinStyleDIB = IS_WIN30_DIB(lpbi);
//DEL for (i = 0; i < (int)wNumColors; i++)
//DEL {
//DEL if (bWinStyleDIB)
//DEL {
//DEL m_lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed;
//DEL m_lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
//DEL m_lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue;
//DEL m_lpPal->palPalEntry[i].peFlags = 0;
//DEL }
//DEL else
//DEL {
//DEL m_lpPal->palPalEntry[i].peRed = lpbmc->bmciColors[i].rgbtRed;
//DEL m_lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen;
//DEL m_lpPal->palPalEntry[i].peBlue = lpbmc->bmciColors[i].rgbtBlue;
//DEL m_lpPal->palPalEntry[i].peFlags = 0;
//DEL }
//DEL }
//DEL // create the palette and get handle to it
//DEL m_pPal=new CPalette;
//DEL bResult = m_pPal->CreatePalette(m_lpPal);
//DEL ::GlobalUnlock((HGLOBAL) hLogPal);
//DEL ::GlobalFree((HGLOBAL) hLogPal);
//DEL }
//DEL ::GlobalUnlock((HGLOBAL) m_hDIB);
//DEL return bResult;
//DEL }
/*************************************************************************
* Function: PaintDIB()
* Parameters:
* CDC*pDC - DC to do output to
* CRect dRect - rectangle on DC to do output to
* CRect sRect - rectangle of DIB to output
* Return Value: TRUE if DIB was drawn, FALSE otherwise
* Description:
* Painting routine for a DIB. Calls StretchDIBits() or
* SetDIBitsToDevice() to paint the DIB. The DIB is
* output to the specified DC, at the coordinates given
* in lpDCRect. The area of the DIB to be output is
* given by lpDIBRect.
*
************************************************************************/
BOOL CDIB::PaintDIB(CDC*pDC,CRect dRect,CRect sRect)
{
LPSTR lpDIBHdr; // Pointer to BITMAPINFOHEADER
LPSTR lpDIBBits; // Pointer to DIB bits
BOOL bSuccess=FALSE; // Success/fail flag
CPalette*pOldPal=NULL; // Previous palette
// Check for valid DIB handle
if (m_hDIB == NULL) return FALSE;
// Lock down the DIB, and get a pointer to the beginning of the bit
// buffer
lpDIBHdr = (LPSTR)::GlobalLock((HGLOBAL)m_hDIB);
lpDIBBits = lpDIBHdr + *(LPDWORD)lpDIBHdr + PaletteSize(lpDIBHdr);
// Get the DIB's palette, then select it into DC
// Select as background since we have
// already realized in forground if needed
if (m_pPal != NULL)
{
pOldPal = pDC->SelectPalette(m_pPal,TRUE);
pDC->RealizePalette();
}
// Make sure to use the stretching mode best for color pictures
pDC->SetStretchBltMode(COLORONCOLOR);
// Determine whether to call StretchDIBits() or SetDIBitsToDevice()
if (dRect.Width()==sRect.Width()&&dRect.Height()==sRect.Height())
bSuccess = ::SetDIBitsToDevice(pDC->m_hDC,dRect.left,dRect.top,
dRect.Width(),dRect.Height(),sRect.left,
m_nHeight-sRect.top-sRect.Height(),0,m_nHeight,
lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS);
else
bSuccess = ::StretchDIBits(pDC->m_hDC,dRect.left,dRect.top,dRect.Width(),
dRect.Height(),sRect.left,sRect.top,sRect.Width(),sRect.Height(),
lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS,SRCCOPY);
::GlobalUnlock((HGLOBAL) m_hDIB);
// Reselect old palette
if (pOldPal != NULL) pDC->SelectPalette(pOldPal, TRUE);
return bSuccess;
}
BOOL CDIB::PaintDIB(HDC pDC,CRect dRect,CRect sRect)
{
LPSTR lpDIBHdr; // Pointer to BITMAPINFOHEADER
LPSTR lpDIBBits; // Pointer to DIB bits
BOOL bSuccess=FALSE; // Success/fail flag
HPALETTE pOldPal=NULL; // Previous palette
// Check for valid DIB handle
if (m_hDIB == NULL) return FALSE;
// Lock down the DIB, and get a pointer to the beginning of the bit
// buffer
lpDIBHdr = (LPSTR)::GlobalLock((HGLOBAL)m_hDIB);
lpDIBBits = lpDIBHdr + *(LPDWORD)lpDIBHdr + PaletteSize(lpDIBHdr);
// Get the DIB's palette, then select it into DC
// Select as background since we have
// already realized in forground if needed
if (m_pPal != NULL)
{
pOldPal = SelectPalette(pDC,(HPALETTE )m_pPal->m_hObject,TRUE);
RealizePalette(pDC);
}
// Make sure to use the stretching mode best for color pictures
SetStretchBltMode(pDC,COLORONCOLOR);
// Determine whether to call StretchDIBits() or SetDIBitsToDevice()
if (dRect.Width()==sRect.Width()&&dRect.Height()==sRect.Height())
bSuccess = SetDIBitsToDevice(pDC,dRect.left,dRect.top,
dRect.Width(),dRect.Height(),sRect.left,
m_nHeight-sRect.top-sRect.Height(),0,m_nHeight,
lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS);
else
bSuccess = ::StretchDIBits(pDC,dRect.left,dRect.top,dRect.Width(),
dRect.Height(),sRect.left,sRect.top,sRect.Width(),sRect.Height(),
lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS,SRCCOPY);
::GlobalUnlock((HGLOBAL) m_hDIB);
// Reselect old palette
if (pOldPal != NULL) SelectPalette(pDC,pOldPal, TRUE);
return bSuccess;
}
DWORD CDIB::DIBWidthByByte()
{
return WIDTHBYTES(m_nWidth*24);
}
/*************************************************************************
* Function: DIBWidth()
* Description:
* This function gets the width of the DIB from the BITMAPINFOHEADER
* width field if it is a Windows 3.0-style DIB or from the BITMAPCOREHEADER
* width field if it is an other-style DIB.
************************************************************************/
int CDIB::DIBWidth()
{
LPSTR lpDIBHdr; // Pointer to BITMAPINFOHEADER
LPBITMAPINFOHEADER lpbmi; // pointer to a Win 3.0-style DIB
LPBITMAPCOREHEADER lpbmc; // pointer to an other-style DIB
int w;
lpDIBHdr=(LPSTR)::GlobalLock((HGLOBAL) m_hDIB);
// point to the header (whether Win 3.0 and old)
lpbmi=(LPBITMAPINFOHEADER)lpDIBHdr;
lpbmc=(LPBITMAPCOREHEADER)lpDIBHdr;
// return the DIB width if it is a Win 3.0 DIB
if (IS_WIN30_DIB(lpDIBHdr))
w=lpbmi->biWidth;
else // it is an other-style DIB, so return its width
w=lpbmc->bcWidth;
::GlobalUnlock((HGLOBAL) m_hDIB);
return(w);
}
/*************************************************************************
* Function: DIBHeight()
* Description:
* This function gets the height of the DIB from the BITMAPINFOHEADER
* height field if it is a Windows 3.0-style DIB or from the BITMAPCOREHEADER
* height field if it is an other-style DIB.
************************************************************************/
int CDIB::DIBHeight()
{
LPSTR lpDIBHdr; // Pointer to BITMAPINFOHEADER
LPBITMAPINFOHEADER lpbmi; // pointer to a Win 3.0-style DIB
LPBITMAPCOREHEADER lpbmc; // pointer to an other-style DIB
int h;
// point to the header (whether old or Win 3.0
lpDIBHdr = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);
lpbmi = (LPBITMAPINFOHEADER)lpDIBHdr;
lpbmc = (LPBITMAPCOREHEADER)lpDIBHdr;
// return the DIB height if it is a Win 3.0 DIB
if (IS_WIN30_DIB(lpDIBHdr))
h=lpbmi->biHeight;
else // it is an other-style DIB, so return its height
h=lpbmc->bcHeight;
::GlobalUnlock((HGLOBAL) m_hDIB);
return(h);
}
/*************************************************************************
* Function: PaletteSize()
* Description:
* This function gets the size required to store the DIB's palette by
* multiplying the number of colors by the size of an RGBQUAD (for a
* Windows 3.0-style DIB) or by the size of an RGBTRIPLE (for an other-
* style DIB).
************************************************************************/
int CDIB::PaletteSize(LPSTR lpbi)
{
// calculate the size required by the palette
if (IS_WIN30_DIB (lpbi))
return DIBNumColors(lpbi) * sizeof(RGBQUAD);
else
return DIBNumColors(lpbi) * sizeof(RGBTRIPLE);
}
/*************************************************************************
* DIBNumColors()
* Description:
* This function calculates the number of colors in the DIB's color table
* by finding the bits per pixel for the DIB (whether Win3.0 or other-style
* DIB). If bits per pixel is 1: colors=2, if 4: colors=16, if 8: colors=256,
* if 24, no colors in color table.
************************************************************************/
int CDIB::DIBNumColors(LPSTR lpbi)
{
WORD wBitCount; // DIB bit count
// If this is a Windows-style DIB, the number of colors in the
// color table can be less than the number of bits per pixel
// allows for (i.e. lpbi->biClrUsed can be set to some value).
// If this is the case, return the appropriate value.
if (IS_WIN30_DIB(lpbi))
{
DWORD dwClrUsed;
dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed;
if (dwClrUsed != 0)
return (WORD)dwClrUsed;
}
// Calculate the number of colors in the color table based on
// the number of bits per pixel for the DIB.
if (IS_WIN30_DIB(lpbi))
wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount;
else
wBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
// return number of colors based on bits per pixel */
switch (wBitCount)
{
case 1:return 2;
case 4:return 16;
case 8:return 256;
default:return 0;
}
}
BOOL CDIB::SaveDIB(CFile & file)
{
BITMAPFILEHEADER bmfHdr; // Header for Bitmap file
LPBITMAPINFOHEADER lpBI; // Pointer to DIB info structure
DWORD dwDIBSize;
if (m_hDIB == NULL)
return FALSE;
// Get a pointer to the DIB memory, the first of which contains a BITMAPINFO structure
lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) m_hDIB);
if (lpBI == NULL)
return FALSE;
if (!IS_WIN30_DIB(lpBI))
{
::GlobalUnlock((HGLOBAL) m_hDIB);
return FALSE; // It's an other-style DIB (save not supported)
}
// Fill in the fields of the file header
/* Fill in file type (first 2 bytes must be "BM" for a bitmap) */
bmfHdr.bfType = DIB_HEADER_MARKER; // "BM"
// Calculating the size of the DIB is a bit tricky (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 up writing out a few too
// many bytes to the file (which may cause problems with some apps).
//
// So, instead let's calculate the size manually (if we can)
//
// First, find size of header plus size of color table. Since the
// first DWORD in both BITMAPINFOHEADER and BITMAPCOREHEADER conains
// the size of the structure, let's use this.
dwDIBSize = *(LPDWORD)lpBI + PaletteSize((LPSTR)lpBI); // Partial Calculation
// Now calculate the size of the image
if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))
{
// It's an RLE bitmap, we can't calculate size, so trust the
// biSizeImage field
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 we
// fill in the biSizeImage field (this will fix any .BMP files which
// have this field incorrect).
lpBI->biSizeImage = dwBmBitsSize;
}
// Calculate the file size by adding the DIB size to sizeof(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 the Bitmap file header plus the DIB header,
* plus the size of the color table.
*/
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize
+ PaletteSize((LPSTR)lpBI);
TRY
{ // Write the file header
file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));
// Write the DIB header and the bits
file.WriteHuge(lpBI, dwDIBSize);
}
CATCH (CFileException, e)
{
::GlobalUnlock((HGLOBAL) m_hDIB);
THROW_LAST();
}
END_CATCH
::GlobalUnlock((HGLOBAL) m_hDIB);
return TRUE;
}
void CDIB::ReadBYTEFile(CFile & file, int size)
{
DWORD dwBitsSize;
LPSTR pDIB;
LPBITMAPINFOHEADER lpBMIH;
LPBITMAPINFO lpbmi;
int i;
dwBitsSize = sizeof(BITMAPINFOHEADER)+(DWORD)256*sizeof(RGBQUAD)+(DWORD)size*(DWORD)size;
m_hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,dwBitsSize);
if (m_hDIB == 0)
{
return ;
}
pDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);
lpBMIH = (LPBITMAPINFOHEADER)pDIB;
lpBMIH->biSize = sizeof(BITMAPINFOHEADER);
lpBMIH->biWidth = (DWORD)size;
lpBMIH->biHeight = (DWORD)size;
m_nWidth=lpBMIH->biWidth;
m_nHeight=lpBMIH->biHeight;
lpBMIH->biPlanes = 1;
lpBMIH->biBitCount = 8;
lpBMIH->biCompression = 0;
lpBMIH->biSizeImage = (DWORD)size*(DWORD)size;
lpBMIH->biXPelsPerMeter = 0;
lpBMIH->biYPelsPerMeter = 0;
lpBMIH->biClrUsed =256;
lpBMIH->biClrImportant =0;
lpbmi=(LPBITMAPINFO)pDIB;
for (i = 0; i < 256; i++)
{
lpbmi->bmiColors[i].rgbRed=i;
lpbmi->bmiColors[i].rgbGreen=i;
lpbmi->bmiColors[i].rgbBlue=i;
lpbmi->bmiColors[i].rgbReserved = 0;
}
if (file.ReadHuge(pDIB+sizeof(BITMAPINFOHEADER)+(DWORD)256*sizeof(RGBQUAD),
lpBMIH->biSizeImage) !=
lpBMIH->biSizeImage)
{
::GlobalUnlock((HGLOBAL) m_hDIB);
::GlobalFree((HGLOBAL) m_hDIB);
return ;
}
::GlobalUnlock((HGLOBAL) m_hDIB);
return ;
}
LPSTR CDIB::FindDIBBits()
{
m_lpbi=(LPSTR)::GlobalLock((LPSTR)m_hDIB);
return (m_lpbi + *(LPDWORD)m_lpbi+PaletteSize(m_lpbi));
// return (lpbi+dwDibOffset-sizeof(BITMAPFILEHEADER));
}
void CDIB::ReadAVIFile(PGETFRAME pframe, int frame)
{
LPSTR lpBuffer,lpBI1,pDIB,p,s1,s2;
LPBITMAPINFOHEADER lpBI,lpBMIH;
DWORD dwDIBSize,size;
LPBITMAPINFO lpbmi;
if(pframe!=NULL)
{
p=(LPSTR)pframe->GetFrame(frame);
if (p!=NULL)
{
lpBI1=(LPSTR)::GlobalLock(p);
lpBI=(LPBITMAPINFOHEADER) lpBI1;
dwDIBSize = *(LPDWORD)lpBI + PaletteSize((LPSTR)lpBI); // Partial Calculation
// Now calculate the size of the image
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 we
// fill in the biSizeImage field (this will fix any .BMP files which
// have this field incorrect).
lpBI->biSizeImage = dwBmBitsSize;
// Calculate the file size by adding the DIB size to sizeof(BITMAPFILEHEADER)
if(lpBI->biBitCount==24){
size= sizeof(BITMAPINFOHEADER)+(DWORD)256*sizeof(RGBQUAD)+(DWORD)lpBI->biWidth*(DWORD)lpBI->biHeight;
lpBuffer=(LPSTR)::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, size);
if(lpBuffer==NULL) return ;
pDIB = (LPSTR) ::GlobalLock((HGLOBAL) lpBuffer);
DWORD i;
lpBMIH = (LPBITMAPINFOHEADER)pDIB;
lpBMIH->biSize = sizeof(BITMAPINFOHEADER);
lpBMIH->biWidth = (DWORD)lpBI->biWidth;//-320+128;
lpBMIH->biHeight = (DWORD) lpBI->biHeight;//-240+128;
m_nWidth=lpBMIH->biWidth;
m_nHeight=lpBMIH->biHeight;
lpBMIH->biPlanes = 1;
lpBMIH->biBitCount = 8;
lpBMIH->biCompression = 0;
lpBMIH->biSizeImage = (DWORD)lpBI->biWidth*(DWORD) lpBI->biHeight;//128*128;
lpBMIH->biXPelsPerMeter = 0;
lpBMIH->biYPelsPerMeter = 0;
lpBMIH->biClrUsed =256;
lpBMIH->biClrImportant =0;
lpbmi=(LPBITMAPINFO)pDIB;
for (i = 0; i < 256; i++)
{
lpbmi->bmiColors[i].rgbRed=(unsigned char)i;
lpbmi->bmiColors[i].rgbGreen=(unsigned char)i;
lpbmi->bmiColors[i].rgbBlue=(unsigned char)i;
lpbmi->bmiColors[i].rgbReserved = 0;
}
dwDIBSize = *(LPDWORD)lpBI + PaletteSize((LPSTR)lpBI); // Partial Calculation
s1=p+dwDIBSize;//+320*100;
s2=pDIB+sizeof(BITMAPINFOHEADER)+(DWORD)256*sizeof(RGBQUAD);
for(i=0;i<lpBMIH->biSizeImage;i++)
{
CopyMemory (s2,s1,1);// +(320-128)*div(i,128).quot*3
s1=s1+3;
s2=s2+1;
}
}
m_hDIB=(HDIB)pDIB;
::GlobalUnlock((HGLOBAL) m_hDIB);
::GlobalUnlock((HGLOBAL) lpBI1);
}
}
return ;
}
void CDIB::Enlarge(CRect & sRect, CRect & dRect)
{
int ix,iy,gx,gy,xd,yd,xs,ys,xdist,ydist,x1,x2,y1,y2;
float deltax,deltay,dx,dx1,dy,dy1,xx,yy,zz;
unsigned char image[512][512];
LPSTR array;
int y,i;
unsigned char** oi;
oi=new unsigned char*[m_nWidth];
array=(LPSTR)FindDIBBits(); // TODO: Add your command handler code here
for(y=0;y<m_nHeight;y++)
{
oi[y]=(unsigned char*)array+m_nWidth*y;
}
for(ix=sRect.left;ix<sRect.right;ix++)
for(iy=sRect.top;iy<sRect.bottom;iy++)
image[iy-sRect.top][ix-sRect.left]=oi[iy][ix];
delete oi;
::GlobalUnlock(array);
xd=dRect.Width();
yd=dRect.Height();
xs=sRect.Width();
ys=sRect.Height();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -