Dib.cpp
上传用户:aqingfeng
上传日期:2014-03-25
资源大小:1839k
文件大小:24k
- // Dib.cpp: implementation of the CDib class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "小波变换.h"
- #include "Dib.h"
- #include "math.h"
- #include "GlobalApi.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #define new DEBUG_NEW
- #endif
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- // 声明串行化过程
- IMPLEMENT_SERIAL(CDib, CObject, 0);
- /*************************************************************************
- *
- * 函数名称:
- * CDib()
- *
- * 输入参数:
- * 无
- *
- * 返回值:
- * 无
- *
- * 说明:
- * 构造函数
- *
- ************************************************************************
- */
- CDib::CDib()
- {
- m_hFile = NULL;
- m_hBitmap = NULL;
- m_hPalette = NULL;
- m_nBmihAlloc = m_nImageAlloc = noAlloc;
- Empty();
- }
- /*************************************************************************
- *
- * 函数名称:
- * CDib()
- *
- * 输入参数:
- * CSize size - 位图尺寸
- * int nBitCount - 象素位数
- *
- * 返回值:
- * 无
- *
- * 说明:
- * 构造函数
- * 根据给定的位图尺寸和象素位数构造CDib对象,并对信息头和调色板分配内存
- * 但并没有给位图数据分配内存
- *
- ************************************************************************
- */
- CDib::CDib(CSize size, int nBitCount)
- {
- m_hFile = NULL;
- m_hBitmap = NULL;
- m_hPalette = NULL;
- m_nBmihAlloc = m_nImageAlloc = noAlloc;
- Empty();
- // 根据象素位数计算调色板尺寸
- ComputePaletteSize(nBitCount);
- // 分配DIB信息头和调色板的内存
- m_lpBMIH = (LPBITMAPINFOHEADER) new
- char[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries];
- // 设置信息头内存分配状态
- m_nBmihAlloc = crtAlloc;
- // 设置信息头中的信息
- m_lpBMIH->biSize = sizeof(BITMAPINFOHEADER);
- m_lpBMIH->biWidth = size.cx;
- m_lpBMIH->biHeight = size.cy;
- m_lpBMIH->biPlanes = 1;
- m_lpBMIH->biBitCount = nBitCount;
- m_lpBMIH->biCompression = BI_RGB;
- m_lpBMIH->biSizeImage = 0;
- m_lpBMIH->biXPelsPerMeter = 0;
- m_lpBMIH->biYPelsPerMeter = 0;
- m_lpBMIH->biClrUsed = m_nColorTableEntries;
- m_lpBMIH->biClrImportant= m_nColorTableEntries;
- // 计算图象数据内存的大小,并设置此DIB的调色板的指针
- ComputeMetrics();
- // 将此DIB的调色板初始化为0
- memset(m_lpvColorTable, 0, sizeof(RGBQUAD) * m_nColorTableEntries);
- // 暂时不分配图象数据内存
- m_lpImage = NULL;
- }
- /*************************************************************************
- *
- * 函数名称:
- * ~CDib()
- *
- * 输入参数:
- * 无
- *
- * 返回值:
- * 无
- *
- * 说明:
- * 析构函数,并释放所有分配的DIB内存
- *
- ************************************************************************
- */
- CDib::~CDib()
- {
- Empty();
- }
- /*************************************************************************
- *
- * 函数名称:
- * GetDimensions()
- *
- * 输入参数:
- * 无
- *
- * 返回值:
- * CSize - DIB的宽度和高度
- *
- * 说明:
- * 返回以象素表示的DIB的宽度和高度
- *
- ************************************************************************
- */
- CSize CDib::GetDimensions()
- {
- if(m_lpBMIH == NULL) return CSize(0, 0);
- return CSize((int) m_lpBMIH->biWidth, (int) m_lpBMIH->biHeight);
- }
- /*************************************************************************
- *
- * 函数名称:
- * UsePalette()
- *
- * 输入参数:
- * CDC* pDC - 要实现调色板的设备上下文指针
- * BOOL bBackground - 如果标记为FALSE(默认值),并且应用
- * - 程序正在前台运行,则Windows将把该调
- * - 色板作为前台调色板来实现(向系统调色
- * - 板中复制尽可能多的颜色)。如果标记为
- * - TURE,则Windows将把该调色板作为后台
- * - 调色板来实现(尽可能相系统调色板映射
- * - 逻辑调色板)
- *
- * 返回值:
- * UINT - 如果成功,则返回映射到系统调色板的逻
- * - 辑调色板的表项数,否则返回GDI_ERROR
- *
- * 说明:
- * 该函数将CDib对象的逻辑调色板选入设备上下文,然后实现该调色板。Draw成员函
- * 数在绘制DIB之前调用UsePalette。
- *
- ************************************************************************
- */
- UINT CDib::UsePalette(CDC* pDC, BOOL bBackground /* = FALSE */)
- {
- // 判断是否存在调色板
- if(m_hPalette == NULL) return 0;
- // 得到设备上下文句柄
- HDC hdc = pDC->GetSafeHdc();
- // 选择调色板到设备上下文
- ::SelectPalette(hdc, m_hPalette, bBackground);
- // 实现该调色板
- return ::RealizePalette(hdc);
- }
- /*************************************************************************
- *
- * 函数名称:
- * Draw()
- *
- * 输入参数:
- * CDC* pDC - 指向将要接收DIB图象的设备上下文指针
- * CPoint origin - 显示DIB的逻辑坐标
- * CSize size - 显示矩形的宽度和高度
- *
- * 返回值:
- * BOOL - 如果成功,则为TRUE,
- *
- * 说明:
- * 通过调用Win32 SDK的StretchDIBits函数将CDib对象输出到显示器(或者打印机)。
- * 为了适合指定的矩形,位图可以进行必要的拉伸
- *
- ************************************************************************
- */
- BOOL CDib::Draw(CDC* pDC, CPoint origin, CSize size)
- {
- // 如果信息头为空,表示尚未有数据,返回FALSE
- if(m_lpBMIH == NULL) return FALSE;
- // 如果调色板不为空,则将调色板选入设备上下文
- if(m_hPalette != NULL) {
- ::SelectPalette(pDC->GetSafeHdc(), m_hPalette, TRUE);
- }
- // 设置显示模式
- pDC->SetStretchBltMode(COLORONCOLOR);
- // 在设备的origin位置上画出大小为size的图象
- ::StretchDIBits(pDC->GetSafeHdc(), origin.x, origin.y,size.cx,size.cy,
- 0, 0, m_lpBMIH->biWidth, m_lpBMIH->biHeight,
- m_lpImage, (LPBITMAPINFO) m_lpBMIH, DIB_RGB_COLORS, SRCCOPY);
- // 返回
- return TRUE;
- }
- /*************************************************************************
- *
- * 函数名称:
- * MakePalette()
- *
- * 输入参数:
- * 无
- *
- * 返回值:
- * BOOL - 如果成功,则为TRUE
- *
- * 说明:
- * 如果颜色表存在的话,该函数将读取它,并创建一个Windows调色板。
- * HPALETTE存储在一个数据成员中。
- *
- ************************************************************************
- */
- BOOL CDib::MakePalette()
- {
- // 如果不存在调色板,则返回FALSE
- if(m_nColorTableEntries == 0) return FALSE;
- if(m_hPalette != NULL) ::DeleteObject(m_hPalette);
- TRACE("CDib::MakePalette -- m_nColorTableEntries = %dn", m_nColorTableEntries);
-
- // 给逻辑调色板分配内存
- LPLOGPALETTE pLogPal = (LPLOGPALETTE) new char[2 * sizeof(WORD) +
- m_nColorTableEntries * sizeof(PALETTEENTRY)];
- // 设置逻辑调色板的信息
- pLogPal->palVersion = 0x300;
- pLogPal->palNumEntries = m_nColorTableEntries;
- // 拷贝DIB中的颜色表到逻辑调色板
- LPRGBQUAD pDibQuad = (LPRGBQUAD) m_lpvColorTable;
- for(int i = 0; i < m_nColorTableEntries; i++) {
- pLogPal->palPalEntry[i].peRed = pDibQuad->rgbRed;
- pLogPal->palPalEntry[i].peGreen = pDibQuad->rgbGreen;
- pLogPal->palPalEntry[i].peBlue = pDibQuad->rgbBlue;
- pLogPal->palPalEntry[i].peFlags = 0;
- pDibQuad++;
- }
- // 创建逻辑调色板
- m_hPalette = ::CreatePalette(pLogPal);
- // 删除临时变量并返回TRUE
- delete pLogPal;
- return TRUE;
- }
- /*************************************************************************
- *
- * 函数名称:
- * SetSystemPalette()
- *
- * 输入参数:
- * CDC* pDC - 设备上下文指针
- *
- * 返回值:
- * BOOL - 如果成功,则为TRUE,
- *
- * 说明:
- * 如果16bpp、24bpp或32bppDIB不具备调色板,则该函数可以为CDib对象创建一个逻辑调色板,
- * 它与由CreatehalftonePalette函数返回的调色板相匹配。如果程序在256色调色板显示器上
- * 运行,而你又没有调用SetSystemPalette,那么,你将不具有任何调色板,只有20中标准的
- * Windows颜色出现在DIB中
- *
- ************************************************************************
- */
- BOOL CDib::SetSystemPalette(CDC* pDC)
- {
- // 如果DIB不具备调色板,则需要利用系统的调色板
- if(m_nColorTableEntries != 0) return FALSE;
-
- // 为设备上下文创建中间调色板,并将其与CPalette对象连接
- m_hPalette = ::CreateHalftonePalette(pDC->GetSafeHdc());
- // 返回
- return TRUE;
- }
- /*************************************************************************
- *
- * 函数名称:
- * CreateBitmap()
- *
- * 输入参数:
- * CDC* pDC - 设备上下文指针
- *
- * 返回值:
- * HBITMAP - 到GDI位图的句柄;如果不成功,则为NULL
- * - 该句柄不是作为公共数据成员存储的
- *
- * 说明:
- * 从已有的DIB中创建DDB位图。不要将这个函数与CreateSection
- * 弄混了,后者的作用是生成DIB并保存句柄
- *
- ************************************************************************
- */
- HBITMAP CDib::CreateBitmap(CDC* pDC)
- {
- // 如果不存在图象数据,则返回NULL
- if (m_dwSizeImage == 0) return NULL;
- // 用指定的DIB来创建DDB,并用DIB信息初始化位图的图象位
- HBITMAP hBitmap = ::CreateDIBitmap(pDC->GetSafeHdc(), m_lpBMIH,
- CBM_INIT, m_lpImage, (LPBITMAPINFO) m_lpBMIH, DIB_RGB_COLORS);
- ASSERT(hBitmap != NULL);
- // 返回DDB位图句柄
- return hBitmap;
- }
- /*************************************************************************
- *
- * 函数名称:
- * ConvertDDBToDIB()
- *
- * 输入参数:
- * HBITMAP hBitmap - 指向源数据的BITMAP句柄
- * CDib* pDibDst - 指向转换目标的CDib对象指针
- *
- * 返回值:
- * BOOL - 如果操作成功,则返回TRUE
- *
- * 说明:
- * 该函数将源BITMAP类pDibSrc中的数据拷贝到pDibDst中,并对相应的数据成员赋值
- *
- *************************************************************************
- */
- BOOL CDib::ConvertFromDDB(HBITMAP hBitmap, HPALETTE hPal)
- {
- // 声明一个BITMAP结构
- BITMAP bm;
- // 设备上下文
- HDC hDC;
-
- // 象素位数
- WORD biBitCount;
-
- // 调色板表项数
- int nColorTableEntries;
- // 如果hBitmap句柄无效,则返回
- if(!hBitmap){
- return FALSE;
- }
-
- // 释放已分配的内存
- Empty();
-
- // 填充图象数据到bm中,其中最后一个参数表示接收这个指定的对象的指针
- if(!GetObject(hBitmap,sizeof(BITMAP),(LPBYTE)&bm)){
- return FALSE;
- }
- // 计算象素位数
- biBitCount=bm.bmPlanes*bm.bmBitsPixel;
- if(biBitCount<=1)
- biBitCount=1;
- else if(biBitCount<=4)
- biBitCount=4;
- else if(biBitCount<=8)
- biBitCount=8;
- else
- biBitCount=24;
- // 计算调色板的尺寸
- // 如果biClrUsed为零,则用到的颜色数为2的biBitCount次方
- switch(biBitCount) {
- case 1:
- nColorTableEntries = 2;
- break;
- case 4:
- nColorTableEntries = 16;
- break;
- case 8:
- nColorTableEntries = 256;
- break;
- case 16:
- case 24:
- case 32:
- nColorTableEntries = 0;
- break;
- default:
- ASSERT(FALSE);
- }
- ASSERT((nColorTableEntries >= 0) && (nColorTableEntries <= 256));
- m_nColorTableEntries = nColorTableEntries;
- // 分配DIB信息头和调色板的内存
- m_lpBMIH = (LPBITMAPINFOHEADER) new char
- [sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * nColorTableEntries];
- m_nBmihAlloc = m_nImageAlloc = crtAlloc;
- m_lpBMIH->biSize = sizeof(BITMAPINFOHEADER);
- m_lpBMIH->biWidth = bm.bmWidth;
- m_lpBMIH->biHeight = bm.bmHeight;
- m_lpBMIH->biPlanes = 1;
- m_lpBMIH->biBitCount = biBitCount;
- m_lpBMIH->biCompression = BI_RGB;
- m_lpBMIH->biSizeImage = 0;
- m_lpBMIH->biXPelsPerMeter = 0;
- m_lpBMIH->biYPelsPerMeter = 0;
- m_lpBMIH->biClrUsed = nColorTableEntries;
- m_lpBMIH->biClrImportant = nColorTableEntries;
- // 获得设备上下文句柄
- hDC=GetDC(NULL);
-
- // 如果没有指定调色板,则从系统中获得当前的系统调色板
- if(hPal==NULL){
- hPal = GetSystemPalette();
- }
- hPal = SelectPalette(hDC, hPal, FALSE);
- RealizePalette(hDC);
-
- // 调用GetDIBits填充信息头,并获得图象数据的尺寸。注意这里图象数据指针为NULL
- GetDIBits( hDC, hBitmap, 0, (UINT)m_lpBMIH->biHeight, NULL, (LPBITMAPINFO)m_lpBMIH, DIB_RGB_COLORS);
- // 如果没有正确的获得图象数据尺寸,则重新计算
- if( m_lpBMIH->biSizeImage == 0 ){
- m_lpBMIH->biSizeImage=(((bm.bmWidth*biBitCount) + 31) / 32 * 4)*bm.bmHeight;
- }
- // 分配存放图象数据的内存
- m_lpImage = (LPBYTE) new char[m_lpBMIH->biSizeImage];
- // 调用GetDIBits加载图象数据,注意这里给出了图象数据指针
- // 如果加载图象数据不成功,则释放已经分配的内存,并返回FALSE
- if( GetDIBits( hDC, hBitmap, 0, (UINT)m_lpBMIH->biHeight, (LPBYTE)m_lpImage,
- (LPBITMAPINFO)m_lpBMIH, DIB_RGB_COLORS) == 0 ){
- //clean up and return NULL
- Empty();
- SelectPalette( hDC, hPal, TRUE );
- RealizePalette( hDC );
- ReleaseDC( NULL, hDC );
-
- return FALSE;
- }
- // 删除临时变量
- SelectPalette(hDC, hPal, TRUE);
- RealizePalette(hDC);
- ReleaseDC(NULL, hDC);
- return TRUE;
- }
- /*************************************************************************
- *
- * 函数名称:
- * Read()
- *
- * 输入参数:
- * CFile* pFile - 指向CFile对象的指针
- *
- * 返回值:
- * BOOL - 如果成功,则返回TRUE
- *
- * 说明:
- * 该函数DIB从一个文件读入CDib对象。该文件必须成功打开。如果该文件是BMP文件
- * 读取工作从文件头开始。如果该文件是一个文档,读取工作则从当前文件指针处开始
- *
- ************************************************************************
- */
- BOOL CDib::Read(CFile* pFile)
- {
- // 释放已经分配的内存
- Empty();
- // 临时存放信息的变量
- int nCount, nSize;
- BITMAPFILEHEADER bmfh;
- // 进行读操作
- try
- {
- // 读取文件头
- nCount = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));
- if(nCount != sizeof(BITMAPFILEHEADER)) {
- throw new CException;
- }
- // 如果文件类型部位"BM",则返回并进行相应错误处理
- if(bmfh.bfType != 0x4d42) {
- throw new CException;
- }
- // 计算信息头加上调色板的大小,并分配相应的内存
- nSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER);
- m_lpBMIH = (LPBITMAPINFOHEADER) new char[nSize];
- m_nBmihAlloc = m_nImageAlloc = crtAlloc;
- // 读取信息头和调色板
- nCount = pFile->Read(m_lpBMIH, nSize);
- // 计算图象数据大小并设置调色板指针
- ComputeMetrics();
- // 计算调色板的表项数
- ComputePaletteSize(m_lpBMIH->biBitCount);
- // 如果DIB中存在调色板,则创建一个Windows调色板
- MakePalette();
- // 分配图象数据内存,并从文件中读取图象数据
- m_lpImage = (LPBYTE) new char[m_dwSizeImage];
- nCount = pFile->Read(m_lpImage, m_dwSizeImage);
- }
- // 错误处理
- catch(CException* pe)
- {
- AfxMessageBox("Read error");
- pe->Delete();
- return FALSE;
- }
- // 返回
- return TRUE;
- }
- /*************************************************************************
- *
- * 函数名称:
- * Write()
- *
- * 输入参数:
- * CFile* pFile - 指向CFile对象的指针
- *
- * 返回值:
- * BOOL - 如果成功,则返回TRUE
- *
- * 说明:
- * 该函数把DIB从CDib对象写进文件中。该文件必须成功打开或者创建
- *
- ************************************************************************
- */
- BOOL CDib::Write(CFile* pFile)
- {
- BITMAPFILEHEADER bmfh;
- // 设置文件头中文件类型为"BM"
- bmfh.bfType = 0x4d42;
- // 计算信息头和调色板的大小尺寸
- int nSizeHdr = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries;
- // 设置文件头信息
- bmfh.bfSize = sizeof(BITMAPFILEHEADER) + nSizeHdr + m_dwSizeImage;
- bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
- bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
- sizeof(RGBQUAD) * m_nColorTableEntries;
-
- // 进行写操作
- try {
- pFile->Write((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));
- pFile->Write((LPVOID) m_lpBMIH, nSizeHdr);
- pFile->Write((LPVOID) m_lpImage, m_dwSizeImage);
- }
- // 错误处理
- catch(CException* pe) {
- pe->Delete();
- AfxMessageBox("write error");
- return FALSE;
- }
- // 返回
- return TRUE;
- }
- /*************************************************************************
- *
- * 函数名称:
- * Serialize()
- *
- * 输入参数:
- * CArchive& ar - 指向应用程序归档对象
- *
- * 返回值:
- * 无
- *
- * 说明:
- * 该函数进行串行化过程,将CDib数据进行读入或者写出
- *
- ************************************************************************
- */
- void CDib::Serialize(CArchive& ar)
- {
- DWORD dwPos;
- // 获得此归档文件的CFile对象指针
- dwPos = ar.GetFile()->GetPosition();
- TRACE("CDib::Serialize -- pos = %dn", dwPos);
- // 从归档文件缓冲区中冲掉未写入数据
- ar.Flush();
- // 重新获得此归档文件的CFile对象指针
- dwPos = ar.GetFile()->GetPosition();
- TRACE("CDib::Serialize -- pos = %dn", dwPos);
- // 确定归档文件是否被存储,是则进行存储
- if(ar.IsStoring()) {
- Write(ar.GetFile());
- }
- // 否则进行加载
- else {
- Read(ar.GetFile());
- }
- }
- /*************************************************************************
- *
- * 函数名称:
- * ComputePaletteSize()
- *
- * 输入参数:
- * int nBitCount - 指向CFile对象的指针
- *
- * 返回值:
- * 无
- *
- * 说明:
- * 该函数根据位图象素位数计算调色板的尺寸
- *
- ************************************************************************
- */
- void CDib::ComputePaletteSize(int nBitCount)
- {
- // 如果biClrUsed为零,则用到的颜色数为2的biBitCount次方
- if((m_lpBMIH == NULL) || (m_lpBMIH->biClrUsed == 0)) {
- switch(nBitCount) {
- case 1:
- m_nColorTableEntries = 2;
- break;
- case 4:
- m_nColorTableEntries = 16;
- break;
- case 8:
- m_nColorTableEntries = 256;
- break;
- case 16:
- case 24:
- case 32:
- m_nColorTableEntries = 0;
- break;
- default:
- ASSERT(FALSE);
- }
- }
- // 否则调色板的表项数就是用到的颜色数目
- else {
- m_nColorTableEntries = m_lpBMIH->biClrUsed;
- }
- ASSERT((m_nColorTableEntries >= 0) && (m_nColorTableEntries <= 256));
- }
- /*************************************************************************
- *
- * 函数名称:
- * ComputeMetrics()
- *
- * 输入参数:
- * 无
- *
- * 返回值:
- * 无
- *
- * 说明:
- * 该函数计算图象位图的尺寸,并对DIB中的调色板的指针进行赋值
- *
- ************************************************************************
- */
- void CDib::ComputeMetrics()
- {
- // 如果结构的长度不对,则进行错误处理
- if(m_lpBMIH->biSize != sizeof(BITMAPINFOHEADER)) {
- TRACE("Not a valid Windows bitmap -- probably an OS/2 bitmapn");
- throw new CException;
- }
- // 保存图象数据内存大小到CDib对象的数据成员中
- m_dwSizeImage = m_lpBMIH->biSizeImage;
- // 如果图象数据内存大小为0,则重新计算
- if(m_dwSizeImage == 0) {
- DWORD dwBytes = ((DWORD) m_lpBMIH->biWidth * m_lpBMIH->biBitCount) / 32;
- if(((DWORD) m_lpBMIH->biWidth * m_lpBMIH->biBitCount) % 32) {
- dwBytes++;
- }
- dwBytes *= 4;
- m_dwSizeImage = dwBytes * m_lpBMIH->biHeight;
- }
- // 设置DIB中的调色板指针
- m_lpvColorTable = (LPBYTE) m_lpBMIH + sizeof(BITMAPINFOHEADER);
- }
- /*************************************************************************
- *
- * 函数名称:
- * Empty()
- *
- * 输入参数:
- * 无
- *
- * 返回值:
- * 无
- *
- * 说明:
- * 该函数清空DIB,释放已分配的内存,并且必要的时候关闭映射文件
- *
- ************************************************************************
- */
- void CDib::Empty()
- {
- // 关闭内存映射文件的连接
- DetachMapFile();
- // 根据内存分配的状态,调用相应的函数释放信息头
- if(m_nBmihAlloc == crtAlloc) {
- delete [] m_lpBMIH;
- }
- else if(m_nBmihAlloc == heapAlloc) {
- ::GlobalUnlock(m_hGlobal);
- ::GlobalFree(m_hGlobal);
- }
- // 释放图象数据内存
- if(m_nImageAlloc == crtAlloc) delete [] m_lpImage;
- // 释放调色板句柄
- if(m_hPalette != NULL) ::DeleteObject(m_hPalette);
- // 如果创建了BITMAP,则进行释放
- if(m_hBitmap != NULL) ::DeleteObject(m_hBitmap);
- // 重新设置内存分配状态
- m_nBmihAlloc = m_nImageAlloc = noAlloc;
- // 释放内存后,还需要将指针设置为NULL并将相应的数据设置为0
- m_hGlobal = NULL;
- m_lpBMIH = NULL;
- m_lpImage = NULL;
- m_lpvColorTable = NULL;
- m_nColorTableEntries = 0;
- m_dwSizeImage = 0;
- m_lpvFile = NULL;
- m_hMap = NULL;
- m_hFile = NULL;
- m_hBitmap = NULL;
- m_hPalette = NULL;
- }
- /*************************************************************************
- *
- * 函数名称:
- * DetachMapFile()
- *
- * 输入参数:
- * 无
- *
- * 返回值:
- * 无
- *
- * 说明:
- * 函数可以释放现有的已分配的内存,并关闭以前关联的任何内存映射文件。
- *
- ************************************************************************
- */
- void CDib::DetachMapFile()
- {
- // 如果没有进行内存映射,则不进行处理
- if(m_hFile == NULL) return;
- // 关闭内存映射
- ::UnmapViewOfFile(m_lpvFile);
- // 关闭内存映射对象和文件
- ::CloseHandle(m_hMap);
- ::CloseHandle(m_hFile);
- m_hFile = NULL;
- }
- /*************************************************************************
- *
- * 函数名称:
- * PaletteSize()
- *
- * 输入参数:
- * 无
- *
- * 返回值:
- * DWORD - 返回调色板的尺寸
- *
- * 说明:
- * 该函数计算机调色板所需的尺寸
- *
- ************************************************************************
- */
- WORD CDib::PaletteSize()
- {
- // 临时变量
- WORD NumColors;
- LPBITMAPINFOHEADER lpbi=m_lpBMIH;
- // 如果biClrUsed为零,且图象象素位数小于8,则计算调色板用到的表项数
- NumColors = ((lpbi)->biClrUsed == 0 && (lpbi)->biBitCount <= 8
- ? (int)(1 << (int)(lpbi)->biBitCount)
- : (int)(lpbi)->biClrUsed);
- // 根据颜色表示的字节数计算调色板的尺寸
- if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
- return NumColors * sizeof(RGBTRIPLE);
- else
- return NumColors * sizeof(RGBQUAD);
- }
- /*************************************************************************
- *
- * 函数名称:
- * IsEmpty()
- *
- * 输入参数:
- * 无
- *
- * 返回值:
- * BOOL - 如果信息头和图象数据为空,则返回TRUE
- *
- * 说明:
- * 判断信息头和图象数据是否为空
- *
- ************************************************************************
- */
- BOOL CDib::IsEmpty()
- {
- if( m_lpBMIH == NULL&&m_lpImage == NULL)
- return TRUE;
- else
- return FALSE;
- }
- /*************************************************************************
- *
- * 函数名称:
- * GetDibSaveDim()
- *
- * 输入参数:
- * 无
- *
- * 返回值:
- * CSize - DIB实际存储的高度和宽度
- *
- * 说明:
- * 该函数函数用来得到dib的实际存储宽度(DWORD对齐)
- *
- ************************************************************************
- */
- CSize CDib::GetDibSaveDim()
- {
- CSize sizeSaveDim;
- sizeSaveDim.cx = ( m_lpBMIH->biWidth * m_lpBMIH->biBitCount + 31)/32 * 4;
- sizeSaveDim.cy = m_lpBMIH->biHeight;
- return sizeSaveDim;
- }
- /*************************************************************************
- *
- * 函数名称:
- * GetPixelOffset()
- *
- * 输入参数:
- * int x - 象素在X轴的坐标
- * int y - 象素在Y轴的坐标
- *
- * 返回值:
- * int - 返回象素在图象数据块中的真实地址
- *
- * 说明:
- * 该函数得到坐标为(x,y)的象素点的真实地址。由于DIB结构中对图象数据排列的
- * 方式为从下到上,从左到右的,所以需要进行转换。
- *
- ************************************************************************
- */
- LONG CDib::GetPixelOffset(int x, int y)
- {
- CSize sizeSaveDim;
- sizeSaveDim = GetDibSaveDim();
- LONG lOffset = (LONG) (sizeSaveDim.cy - y - 1) * sizeSaveDim.cx +
- x / (8 / m_lpBMIH->biBitCount);
- return lOffset;
- }
- /*************************************************************************
- *
- * 函数名称:
- * GetPixel()
- *
- * 输入参数:
- * int x - 象素在X轴的坐标
- * int y - 象素在Y轴的坐标
- *
- * 返回值:
- * RGBQUAD - 返回DIB在该点真实的颜色
- *
- * 说明:
- * 该函数得到DIB图象在该点真是的颜色。
- *
- ************************************************************************
- */
- RGBQUAD CDib::GetPixel(int x, int y)
- {
- // 颜色结构
- RGBQUAD cColor;
-
- // 根据每象素比特数得到此点的象素值
- switch (m_lpBMIH->biBitCount)
- {
- case 1 :
- if (1<<(7-x%8) & *(LPBYTE)(m_lpImage+GetPixelOffset(x, y)))
- {
- cColor.rgbBlue = 255;
- cColor.rgbGreen = 255;
- cColor.rgbRed = 255;
- cColor.rgbReserved =0;
- }
- else
- {
- cColor.rgbBlue = 0;
- cColor.rgbGreen = 0;
- cColor.rgbRed = 0;
- cColor.rgbReserved =0;
- }
- break;
- case 4 :
- {
- int nIndex = (*(LPBYTE)(m_lpImage+GetPixelOffset(x, y)) &
- (x%2 ? 0x0f : 0xf0)) >> (x%2 ? 0 : 4);
- LPRGBQUAD pDibQuad = (LPRGBQUAD) (m_lpvColorTable) + nIndex;
- cColor.rgbBlue = pDibQuad->rgbBlue;
- cColor.rgbGreen = pDibQuad->rgbGreen;
- cColor.rgbRed = pDibQuad->rgbRed;
- cColor.rgbReserved =0;
- }
- break;
- case 8 :
- {
- int nIndex = *(BYTE*)(m_lpImage+GetPixelOffset(x, y));
- LPRGBQUAD pDibQuad = (LPRGBQUAD) (m_lpvColorTable) + nIndex;
- cColor.rgbBlue = pDibQuad->rgbBlue;
- cColor.rgbGreen = pDibQuad->rgbGreen;
- cColor.rgbRed = pDibQuad->rgbRed;
- cColor.rgbReserved =0;
- }
- break;
- default:
- int nIndex = *(BYTE*)(m_lpImage+GetPixelOffset(x, y));
- cColor.rgbRed = m_lpImage[nIndex];
- cColor.rgbGreen = m_lpImage[nIndex + 1];
- cColor.rgbBlue = m_lpImage[nIndex + 2];
- cColor.rgbReserved =0;
- break;
- }
- // 返回颜色结构
- return cColor;
- }