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

📄 dibapi.cpp

📁 是一种采用哈夫曼算法的图像压缩算法
💻 CPP
字号:
//***********************************************
//文件名:DIBAPI.CPP
//
//DIB(Independent Bitmap)API函数库:
//PaintDIB( )         -绘制API对象
//CreateDIBPalette( ) -创建DIB对象调色板
//FindDIBBits( )      -返回DIB图象像素起始位置
//DIBWidth( )         -返回DIB高度
//DIBHeight( )        -返回DIB宽度
//PaletteSize( )      -返回DIB调色板大小
//DIBNumColors( )     -计算DIB调色板颜色数目
//CopyHandle( )       -拷贝内存块
//SaveDIB( )          -将DIB保存到指定文件中
//ReadDIBFile( )      -重指定文件中读取DIB对象
//
//************************************************


#include "stdafx.h"
#include "dibapi.h"
#include "io.h"
#include "errno.h"

#include "math.h"
#include "direct.h"

/*  Dib文件头标志(字符串“BM”,写DIB时用到该常数)  */

#define DIB_HEADER_MARKER    ((WORD)('M'<<8 )| 'B')

//*************************************************
BOOL WINAPI PaintDIB(HDC hDC,LPRECT lpDCRect,HDIB hDIB,LPRECT lpDIBRect,CPalette *pPal)
{ LPSTR lpDIBHdr;            //BITMAPINFOHEADER指针
  LPSTR lpDIBBits;           //DIB像素指针
  BOOL bSuccess=FALSE;       //成功标志
  HPALETTE hPal=NULL;        //DIB调色板
  HPALETTE hOldPal=NULL;     //以前的调色板

  if(hDIB==NULL)
  { return FALSE;  
  }

  lpDIBHdr=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
  lpDIBBits=::FindDIBBits(lpDIBHdr);
  if(pPal!=NULL)
  { hPal=(HPALETTE)pPal->m_hObject;
  hOldPal=::SelectPalette(hDC,hPal,TRUE);
  }

  ::SetStretchBltMode(hDC,COLORONCOLOR);
  if((RECTWIDTH(lpDCRect)==RECTWIDTH(lpDIBRect)) &&
	 (RECTHEIGHT(lpDCRect)==RECTHEIGHT(lpDIBRect)))
  { bSuccess=::SetDIBitsToDevice(hDC,
                                lpDCRect->left,
								lpDCRect->top,
								RECTWIDTH(lpDCRect),
								RECTHEIGHT(lpDCRect),
								lpDIBRect->left,
								(int)DIBHeight(lpDIBHdr)-lpDIBRect->top-RECTHEIGHT(lpDIBRect),
								0,
								(WORD)DIBHeight(lpDIBHdr),
								lpDIBBits,
								(LPBITMAPINFO)lpDIBHdr,
								DIB_RGB_COLORS);
  }
  else
  { bSuccess=::StretchDIBits(hDC,
                              lpDCRect->left,
							  lpDCRect->top,
							  RECTWIDTH(lpDCRect),
							  RECTHEIGHT(lpDCRect),
							  lpDIBRect->left,
							  lpDIBRect->top,
							  RECTWIDTH(lpDIBRect),
							  RECTHEIGHT(lpDIBRect),
							  lpDIBBits,
							  (LPBITMAPINFO)lpDIBHdr,
							  DIB_RGB_COLORS,
							  SRCCOPY);
  }
  ::GlobalUnlock((HGLOBAL)hDIB);
  if(hOldPal!=NULL)
  { ::SelectPalette(hDC,hOldPal,TRUE);
  }
  return bSuccess;
}

//********************************************************

BOOL WINAPI CreateDIBPalette(HDIB hDIB,CPalette *pPal)
{ LPLOGPALETTE lpPal;
  HANDLE hLogPal;
  HPALETTE hPal=NULL;
  int i;
  WORD wNumColors;
  LPSTR lpbi;
  LPBITMAPINFO lpbmi;  //win3.0
  LPBITMAPCOREINFO lpbmc;
  BOOL bWinStyleDIB;
  BOOL bResult=FALSE;
  
  if(hDIB==NULL)
  { return FALSE; 
  }
  lpbi=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
  lpbmi=(LPBITMAPINFO)lpbi;
  lpbmc=(LPBITMAPCOREINFO)lpbi;
  wNumColors=::DIBNumColors(lpbi);
  if(wNumColors!=0)
  { hLogPal=::GlobalAlloc(GHND,sizeof(LOGPALETTE)
                               +sizeof(PALETTEENTRY)
							   *wNumColors);
    if(hLogPal==0)
	{ ::GlobalUnlock((HGLOBAL)hDIB);
	   return FALSE;
	}
	lpPal=(LPLOGPALETTE)::GlobalLock((HGLOBAL)hLogPal);
	lpPal->palVersion=PALVERSION;
	lpPal->palNumEntries=(WORD)wNumColors;
    bWinStyleDIB=IS_WIN30_DIB(lpbi);
    for(i=0;i<(int)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;
	  }
	}
	bResult=pPal->CreatePalette(lpPal);
	::GlobalUnlock((HGLOBAL)hLogPal);
	::GlobalFree((HGLOBAL)hLogPal);
  }
  ::GlobalUnlock((HGLOBAL)hDIB);
  return bResult;
}

//*******************************************************

LPSTR WINAPI FindDIBBits(LPSTR lpbi)
{ return (lpbi+*(LPDWORD)lpbi+::PaletteSize(lpbi));
}

//*******************************************************

DWORD WINAPI DIBWidth(LPSTR lpDIB)
{ LPBITMAPINFOHEADER lpbmi;
  LPBITMAPCOREHEADER lpbmc;
  lpbmi=(LPBITMAPINFOHEADER)lpDIB;
  lpbmc=(LPBITMAPCOREHEADER)lpDIB;
  if(IS_WIN30_DIB(lpDIB))
  { return lpbmi->biWidth;
  }
  else
  { return(DWORD)lpbmc->bcWidth;
  }
}

//*******************************************************

DWORD WINAPI DIBHeight(LPSTR lpDIB)
{ LPBITMAPINFOHEADER lpbmi;
  LPBITMAPCOREHEADER lpbmc;
  lpbmi=(LPBITMAPINFOHEADER)lpDIB;
  lpbmc=(LPBITMAPCOREHEADER)lpDIB;

  if(IS_WIN30_DIB(lpDIB))
  { return lpbmi->biHeight;
  }
  else
  { return (DWORD)lpbmc->bcHeight;
  }
}

//*******************************************************

WORD WINAPI PaletteSize(LPSTR lpbi)
{ if(IS_WIN30_DIB(lpbi)) 
	{ return(WORD)(::DIBNumColors(lpbi)*sizeof(RGBQUAD));
	}
  else
	{ return(WORD)(::DIBNumColors(lpbi)*sizeof(RGBTRIPLE));
	}
}

//*******************************************************

WORD WINAPI DIBNumColors(LPSTR lpbi)
{ WORD wBitCount;
  if(IS_WIN30_DIB(lpbi))
  { DWORD dwClrUsed;
    dwClrUsed=((LPBITMAPINFOHEADER)lpbi)->biClrUsed;
    if(dwClrUsed!=0)
	{ return (WORD)dwClrUsed;
	}
  }
  if(IS_WIN30_DIB(lpbi))
  { wBitCount=((LPBITMAPINFOHEADER)lpbi)->biBitCount;
  }
  else
  { wBitCount=((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
  }

  switch(wBitCount)
  { case 1:   return 2;
	case 4:   return 16;
	case 8:   return 256;
    default:  return 0;
  }
}

//********************************************************

HGLOBAL WINAPI CopyHandle(HGLOBAL h)
{ if(h==NULL)
    return NULL;
  DWORD dwLen=::GlobalSize((HGLOBAL)h);
  HGLOBAL hCopy=::GlobalAlloc(GHND,dwLen);
  if(hCopy!=NULL)
  { void *lpCopy=::GlobalLock((HGLOBAL)hCopy);
    void *lp    =::GlobalLock((HGLOBAL)h);
	memcpy(lpCopy,lp,dwLen);
	::GlobalUnlock(hCopy);
	::GlobalUnlock(h);
  }
  return hCopy;
}

//*******************************************************

BOOL WINAPI SaveDIB(HDIB hDib,CFile &file)
{ BITMAPFILEHEADER bmfHdr;
  LPBITMAPINFOHEADER lpBI;
  DWORD dwDIBSize;

  if(hDib==NULL)
  { return FALSE;
  }
  lpBI=(LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL)hDib);
  if(lpBI==NULL)
  { return FALSE;
  }
  if(!IS_WIN30_DIB(lpBI))
  { ::GlobalUnlock((HGLOBAL)hDib);
    return FALSE;
  }

  bmfHdr.bfType=DIB_HEADER_MARKER;
  dwDIBSize=*(LPDWORD)lpBI+::PaletteSize((LPSTR)lpBI);
  if((lpBI->biCompression==BI_RLE8)||(lpBI->biCompression==BI_RLE4))
  { dwDIBSize+=lpBI->biSizeImage;
  }
  else
  { DWORD dwBmBitsSize;
    dwBmBitsSize=WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount))*
		        lpBI->biHeight;
	dwDIBSize+=dwBmBitsSize;
    lpBI->biSizeImage=dwBmBitsSize;
  }

  bmfHdr.bfSize=dwDIBSize+sizeof(BITMAPINFOHEADER);
  bmfHdr.bfReserved1=0;
  bmfHdr.bfReserved2=0;

  bmfHdr.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+lpBI->biSize
	                                  +PaletteSize((LPSTR)lpBI);

  TRY
  { file.Write((LPSTR)&bmfHdr,sizeof(BITMAPFILEHEADER));
    file.WriteHuge(lpBI,dwDIBSize);
  }
  CATCH(CFileException,e)
  { ::GlobalUnlock((HGLOBAL)hDib);
    THROW_LAST();
  }
  END_CATCH

  ::GlobalUnlock((HGLOBAL)hDib);
  return TRUE;
}

//********************************************************

HDIB WINAPI ReadDIBFile(CFile &file)
{ BITMAPFILEHEADER bmfHeader;
  DWORD dwBitsSize;
  HDIB hDIB;
  LPSTR pDIB;

  dwBitsSize=file.GetLength();
  if(file.Read((LPSTR)&bmfHeader,sizeof(bmfHeader))!=sizeof(bmfHeader))
  { return NULL;
  }

  if(bmfHeader.bfType!=DIB_HEADER_MARKER)
  { return NULL;
  } 

  hDIB=(HDIB)::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,dwBitsSize);
  if(hDIB==0)
  { return NULL;
  }
  pDIB=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
  if(file.ReadHuge(pDIB,dwBitsSize-sizeof(BITMAPFILEHEADER))!=
	  dwBitsSize-sizeof(BITMAPFILEHEADER))
  { ::GlobalUnlock((HGLOBAL)hDIB);
    ::GlobalFree((HGLOBAL)hDIB);
	return NULL;
  }
  ::GlobalUnlock((HGLOBAL)hDIB);
  return hDIB;
}

⌨️ 快捷键说明

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