www.pudn.com > Palm.rar > dibapi.cpp


//  dibapi.cpp 
// 
//  Source file for Device-Independent Bitmap (DIB) API.  Provides 
//  the following functions: 
// 
//  PaintDIB()          - Painting routine for a DIB 
//  CreateDIBPalette()  - Creates a palette from a DIB 
//  FindDIBBits()       - Returns a pointer to the DIB bits 
//  DIBWidth()          - Gets the width of the DIB 
//  DIBHeight()         - Gets the height of the DIB 
//  PaletteSize()       - Gets the size required to store the DIB's palette 
//  DIBNumColors()      - Calculates the number of colors 
//                        in the DIB's color table 
//  CopyHandle()        - Makes a copy of the given global memory block 
// 
// This is a part of the Microsoft Foundation Classes C++ library. 
// Copyright (C) 1992-1997 Microsoft Corporation 
// All rights reserved. 
// 
// This source code is only intended as a supplement to the 
// Microsoft Foundation Classes Reference and related 
// electronic documentation provided with the library. 
// See these sources for detailed information regarding the 
// Microsoft Foundation Classes product. 
 
#include "stdafx.h" 
#include "dibapi.h" 
#include  
#include  
#include  
#include "allocmem.h" 
#define DIB_HEADER_MARKER   ((WORD) ('M' << 8) | 'B') 
 
#ifdef _MAC 
#define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x)) 
#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x))) 
void ByteSwapHeader(BITMAPFILEHEADER* bmiHeader); 
void ByteSwapInfo(LPSTR lpHeader, BOOL fWin30Header); 
#endif 
#define PI 3.14159 
//角度到弧度转化的宏 
#define RADIAN(angle) ((angle)*PI/180.0)  
/************************************************************************* 
 * 
 * PaintDIB() 
 * 
 * Parameters: 
 * 
 * HDC hDC          - DC to do output to 
 * 
 * LPRECT lpDCRect  - rectangle on DC to do output to 
 * 
 * HDIB hDIB        - handle to global memory with a DIB spec 
 *                    in it followed by the DIB bits 
 * 
 * LPRECT lpDIBRect - rectangle of DIB to output into lpDCRect 
 * 
 * CPalette* pPal   - pointer to CPalette containing DIB's palette 
 * 
 * Return Value: 
 * 
 * BOOL             - 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. 
 * 
 ************************************************************************/ 
 
 
void WINAPI decomposition(double* image,double* c,double* d,int n,int s) 
{     
	int i,ii; 
	double* tmp; 
	tmp = (double *) calloc (n, sizeof(double)); 
	for (i = 0; i < n; i++) 
		tmp[i] = image[i]; 
	for (i = 0; i < n/2; i++)  
	   { 
		ii = i << 1; 
		c[i] = (tmp[ii] + tmp[ii+1]) / 2; 
		d[i] =(tmp[ii] - tmp[ii+1]) / 2; 
	} 
	free((char *)tmp); 
} 
 
 
void WINAPI reconstruction(double* x, double* c,double* d,int n,int s) 
{ 
	int i,  ii; 
	double *tmp; 
	tmp = (double *) calloc (n*2, sizeof(double)); 
	 
	/* haar basis */ 
	for (i = 0; i < n; i++)  
	{ 
		ii = i << 1; 
		tmp[ii]   = c[i] + d[i]; 
		tmp[ii+1] = c[i] - d[i]; 
	}		 
	for (i = 0; i < n*2; i++) 
		x[i] = tmp[i]; 
	free((char *)tmp); 
} 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
HDIB WINAPI MidFilter(HDIB hDIB,int tem_w,int tem_h) 
{ 
 
    //统计中间值 
    double mid; 
 
	BYTE *temp=(BYTE*)malloc(tem_w*tem_h*sizeof(BYTE)); 
 
    //指向图像起始位置的指针 
    BYTE *lpDIB=(BYTE*)::GlobalLock((HGLOBAL) hDIB); 
 
	//指向象素起始位置的指针 
	BYTE *pScrBuff =(BYTE*)::FindDIBBits((char*)lpDIB); 
    
	//获取图像的颜色信息 
    int numColors=(int) ::DIBNumColors((char *)lpDIB); 
 
    //如果图像不是256色返回 
     if (numColors!=256)  
	 {    
        //解除锁定 
	  	::GlobalUnlock((HGLOBAL) hDIB); 
 
		//返回 
		return(hDIB); 
	 } 
     
    //将指向图像象素起始位置的指针,赋值给指针变量 
    BYTE* oldbuf = pScrBuff; 
 
    //循环变量 
    int i,j,m,n; 
 
	int w, h, dw; 
 
	//获取图像的宽度 
	w = (int) ::DIBWidth((char *)lpDIB); 
	 
	//获取图像的高度 
	h = (int) ::DIBHeight((char *)lpDIB); 
	 
	//计算图像每行的字节数 
	dw = (w+3)/4*4;       
	 
	//建立一个和原图像大小相同的25色灰度位图 
    HDIB newhDIB=NewDIB(w,h,8);   
     
	//指向新的位图的指针 
	BYTE *newlpDIB=(BYTE*)::GlobalLock((HGLOBAL) newhDIB); 
 
	//指向新的位图的象素起始位置的指针  
    BYTE *destBuf = (BYTE*)FindDIBBits((char *)newlpDIB); 
     
   //将指向新图像象素起始位置的指针,赋值给指针变量 
    BYTE *newbuf=destBuf;  
	 
	//对图像进行扫描 
    
	//行  
    for(i=0;i(w-(tem_w+1)/2) || i<((tem_h-1)/2) || i>(h-(tem_h+1)/2) ) 
	      *(newbuf+i*dw+j)=*(oldbuf+i*dw+j); 
		  
         //对于其他的象素进行模板操作 
		 else  
         {  
 
          //将点(i,j)点作为模板的中心 
          for(m=i-((tem_h-1)/2);m<=i+((tem_h-1)/2);m++) 
          { 
		     for(n=j-((tem_w-1)/2);n<=j+((tem_w-1)/2);n++) 
		     
             //将以点(i,j)为中心,与模板大小相同的范围内的象素传递到模板矩阵中 
		     temp[(m-i+((tem_h-1)/2))*tem_w+n-j+((tem_w-1)/2)]=*(oldbuf+m*dw+n); 
		   
		  } 
           
		 //利用气泡法计算中值 
           for(m=0;mtemp[n+1])  
			    mid=temp[n]; 
                temp[n]=temp[n+1]; 
			    temp[n+1]=mid; 
			  } 
		    
		   }  
 
           //将计算的结果放到新的位图的相应位置 
	      *(newbuf+i*dw+j)=temp[(tem_w*tem_h-1)/2]; 
		 } 
	   } 
	}  
    
	//解除锁定 
	::GlobalUnlock((HGLOBAL)hDIB); 
     
	//返回新的位图的句柄 
    return(newhDIB); 
} 
 
BOOL WINAPI TranslationDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, LONG lXOffset, LONG lYOffset) 
{ 
	// 指向源图像的指针 
	LPSTR	lpSrc; 
	 
	// 指向要复制区域的指针 
	LPSTR	lpDst; 
	 
	// 指向复制图像的指针 
	LPSTR	lpNewDIBBits; 
	HLOCAL	hNewDIBBits; 
 
	// 象素在新DIB中的坐标 
	LONG	i; 
	LONG	j; 
	 
	// 象素在源DIB中的坐标 
	LONG	i0; 
	LONG	j0; 
	 
	// 图像每行的字节数 
	LONG lLineBytes; 
	 
	// 计算图像每行的字节数 
	lLineBytes = WIDTHBYTES(lWidth * 8); 
	 
	// 暂时分配内存,以保存新图像 
	hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight); 
	if (hNewDIBBits == NULL) 
	{ 
		// 分配内存失败 
		return FALSE; 
	} 
	 
	// 锁定内存 
	lpNewDIBBits = (char * )LocalLock(hNewDIBBits); 
	 
	// 每行 
	for(i = 0; i < lHeight; i++) 
	{ 
		// 每列 
		for(j = 0; j < lWidth; j++) 
		{ 
			// 指向新DIB第i行,第j个象素的指针 
			// 注意由于DIB中图像第一行其实保存在最后一行的位置,因此lpDst 
			// 值不是(char *)lpNewDIBBits + lLineBytes * i + j,而是 
			// (char *)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j 
			lpDst = (char *)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j; 
			 
			// 计算该象素在源DIB中的坐标 
			i0 = i - lXOffset; 
			j0 = j - lYOffset; 
			 
			// 判断是否在源图范围内 
			if( (j0 >= 0) && (j0 < lWidth) && (i0 >= 0) && (i0 < lHeight)) 
			{ 
				// 指向源DIB第i0行,第j0个象素的指针 
				// 同样要注意DIB上下倒置的问题 
				lpSrc = (char *)lpDIBBits + lLineBytes * (lHeight - 1 - i0) + j0; 
				 
				// 复制象素 
				*lpDst = *lpSrc; 
			} 
			else 
			{ 
				// 对于源图中没有的象素,直接赋值为255 
				* ((unsigned char*)lpDst) = 255; 
			} 
			 
		} 
	} 
	 
	// 复制平移后的图像 
	memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight); 
	 
	// 释放内存 
	LocalUnlock(hNewDIBBits); 
	LocalFree(hNewDIBBits); 
	 
	// 返回 
	return TRUE; 
} 
HGLOBAL WINAPI RotateDIB(LPSTR lpDIB, int iRotateAngle) 
{ 
	 
	// 源图像的宽度和高度 
	LONG	lWidth; 
	LONG	lHeight; 
	 
	// 旋转后图像的宽度和高度 
	LONG	lNewWidth; 
	LONG	lNewHeight; 
	 
	// 图像每行的字节数 
	LONG	lLineBytes; 
	 
	// 旋转后图像的宽度(lNewWidth',必须是4的倍数) 
	LONG	lNewLineBytes; 
	 
	// 指向源图像的指针 
	LPSTR	lpDIBBits; 
	 
	// 指向源象素的指针 
	LPSTR	lpSrc; 
	 
	// 旋转后新DIB句柄 
	HDIB	hDIB; 
	 
	// 指向旋转图像对应象素的指针 
	LPSTR	lpDst; 
	 
	// 指向旋转图像的指针 
	LPSTR	lpNewDIB; 
	LPSTR	lpNewDIBBits; 
	 
	// 指向BITMAPINFO结构的指针(Win3.0) 
	LPBITMAPINFOHEADER lpbmi; 
	 
	// 指向BITMAPCOREINFO结构的指针 
	LPBITMAPCOREHEADER lpbmc; 
	 
	// 循环变量(象素在新DIB中的坐标) 
	LONG	i; 
	LONG	j; 
	 
	// 象素在源DIB中的坐标 
	LONG	i0; 
	LONG	j0; 
	 
	// 旋转角度(弧度) 
	float	fRotateAngle; 
	 
	// 旋转角度的正弦和余弦 
	float	fSina, fCosa; 
	 
	// 源图四个角的坐标(以图像中心为坐标系原点) 
	float	fSrcX1,fSrcY1,fSrcX2,fSrcY2,fSrcX3,fSrcY3,fSrcX4,fSrcY4; 
	 
	// 旋转后四个角的坐标(以图像中心为坐标系原点) 
	float	fDstX1,fDstY1,fDstX2,fDstY2,fDstX3,fDstY3,fDstX4,fDstY4; 
	 
	// 两个中间常量 
	float	f1,f2; 
	 
	// 找到源DIB图像象素起始位置 
	lpDIBBits = ::FindDIBBits(lpDIB); 
	 
	// 获取图像的"宽度"(4的倍数) 
	lWidth = ::DIBWidth(lpDIB); 
	 
	// 计算图像每行的字节数 
	lLineBytes = WIDTHBYTES(lWidth * 8); 
	 
	// 获取图像的高度 
	lHeight = ::DIBHeight(lpDIB); 
	 
	// 将旋转角度从度转换到弧度 
	fRotateAngle = (float) RADIAN(iRotateAngle); 
	 
	// 计算旋转角度的正弦 
	fSina = (float) sin((double)fRotateAngle); 
	 
	// 计算旋转角度的余弦 
	fCosa = (float) cos((double)fRotateAngle); 
	 
	// 计算原图的四个角的坐标(以图像中心为坐标系原点) 
	fSrcX1 = (float) (- (lWidth  - 1) / 2); 
	fSrcY1 = (float) (  (lHeight - 1) / 2); 
	fSrcX2 = (float) (  (lWidth  - 1) / 2); 
	fSrcY2 = (float) (  (lHeight - 1) / 2); 
	fSrcX3 = (float) (- (lWidth  - 1) / 2); 
	fSrcY3 = (float) (- (lHeight - 1) / 2); 
	fSrcX4 = (float) (  (lWidth  - 1) / 2); 
	fSrcY4 = (float) (- (lHeight - 1) / 2); 
	 
	// 计算新图四个角的坐标(以图像中心为坐标系原点) 
	fDstX1 =  fCosa * fSrcX1 + fSina * fSrcY1; 
	fDstY1 = -fSina * fSrcX1 + fCosa * fSrcY1; 
	fDstX2 =  fCosa * fSrcX2 + fSina * fSrcY2; 
	fDstY2 = -fSina * fSrcX2 + fCosa * fSrcY2; 
	fDstX3 =  fCosa * fSrcX3 + fSina * fSrcY3; 
	fDstY3 = -fSina * fSrcX3 + fCosa * fSrcY3; 
	fDstX4 =  fCosa * fSrcX4 + fSina * fSrcY4; 
	fDstY4 = -fSina * fSrcX4 + fCosa * fSrcY4; 
	 
	// 计算旋转后的图像实际宽度 
	lNewWidth  = (LONG) ( max( fabs(fDstX4 - fDstX1), fabs(fDstX3 - fDstX2) ) + 0.5); 
	 
	// 计算新图像每行的字节数 
	lNewLineBytes = WIDTHBYTES(lNewWidth * 8); 
	 
	// 计算旋转后的图像高度 
	lNewHeight = (LONG) ( max( fabs(fDstY4 - fDstY1), fabs(fDstY3 - fDstY2) )  + 0.5); 
	 
	// 两个常数,这样不用以后每次都计算了 
	f1 = (float) (-0.5 * (lNewWidth - 1) * fCosa - 0.5 * (lNewHeight - 1) * fSina 
		+ 0.5 * (lWidth  - 1)); 
	f2 = (float) ( 0.5 * (lNewWidth - 1) * fSina - 0.5 * (lNewHeight - 1) * fCosa 
		+ 0.5 * (lHeight - 1)); 
	 
	// 分配内存,以保存新DIB 
	hDIB = (HDIB) ::GlobalAlloc(GHND, lNewLineBytes * lNewHeight + *(LPDWORD)lpDIB + ::PaletteSize(lpDIB)); 
	 
	// 判断是否内存分配失败 
	if (hDIB == NULL) 
	{ 
		// 分配内存失败 
		return NULL; 
	} 
 
	// 锁定内存 
	lpNewDIB =  (char * )::GlobalLock((HGLOBAL) hDIB); 
	 
	// 复制DIB信息头和调色板 
	memcpy(lpNewDIB, lpDIB, *(LPDWORD)lpDIB + ::PaletteSize(lpDIB)); 
	 
	// 找到新DIB象素起始位置 
	lpNewDIBBits = ::FindDIBBits(lpNewDIB); 
	 
	// 获取指针 
	lpbmi = (LPBITMAPINFOHEADER)lpNewDIB; 
	lpbmc = (LPBITMAPCOREHEADER)lpNewDIB; 
 
	// 更新DIB中图像的高度和宽度 
	if (IS_WIN30_DIB(lpNewDIB)) 
	{ 
		// 对于Windows 3.0 DIB 
		lpbmi->biWidth = lNewWidth; 
		lpbmi->biHeight = lNewHeight; 
	} 
	else 
	{ 
		// 对于其它格式的DIB 
		lpbmc->bcWidth = (unsigned short) lNewWidth; 
		lpbmc->bcHeight = (unsigned short) lNewHeight; 
	} 
	 
	// 针对图像每行进行操作 
	for(i = 0; i < lNewHeight; i++) 
	{ 
		// 针对图像每列进行操作 
		for(j = 0; j < lNewWidth; j++) 
		{ 
			// 指向新DIB第i行,第j个象素的指针 
			// 注意此处宽度和高度是新DIB的宽度和高度 
			lpDst = (char *)lpNewDIBBits + lNewLineBytes * (lNewHeight - 1 - i) + j; 
			 
			// 计算该象素在源DIB中的坐标 
			i0 = (LONG) (-((float) j) * fSina + ((float) i) * fCosa + f2 + 0.5); 
			j0 = (LONG) ( ((float) j) * fCosa + ((float) i) * fSina + f1 + 0.5); 
			 
			// 判断是否在源图范围内 
			if( (j0 >= 0) && (j0 < lWidth) && (i0 >= 0) && (i0 < lHeight)) 
			{ 
				// 指向源DIB第i0行,第j0个象素的指针 
				lpSrc = (char *)lpDIBBits + lLineBytes * (lHeight - 1 - i0) + j0; 
				 
				// 复制象素 
				*lpDst = *lpSrc; 
			} 
			else 
			{ 
				// 对于源图中没有的象素,直接赋值为255 
				* ((unsigned char*)lpDst) = 255; 
			} 
			 
		} 
		 
	} 
	 
	// 返回 
	return hDIB; 
} 
 
BYTE ** FillDibToArray(HDIB hDIB) 
{ 
	BYTE* lpDIB=(BYTE*)::GlobalLock ((HGLOBAL)hDIB); 
	BYTE* lpDIBBits=(BYTE*)::FindDIBBits((char*)lpDIB); 
	BYTE* lpSrc=lpDIBBits;	 
	LONG lHeight=::DIBHeight ((char*)lpDIB); 
	LONG lWidth=::DIBWidth ((char*)lpDIB); 
	BYTE** tempdibarray = alloc_2d_byt(lHeight,lWidth); 
	LONG lLineBytes = WIDTHBYTES(lWidth * 8); 
	for(int i=0;ibiWidth = lNewWidth; 
		lpbmi->biHeight = lNewHeight; 
	} 
	else 
	{ 
		// 对于其它格式的DIB 
		lpbmc->bcWidth = (unsigned short) lNewWidth; 
		lpbmc->bcHeight = (unsigned short) lNewHeight; 
	} 
	 
	// 针对图像每行进行操作 
	for(i = 0; i < lNewHeight; i++) 
	{ 
		// 针对图像每列进行操作 
		for(j = 0; j < lNewWidth; j++) 
		{ 
			 
			// 指向新DIB第i行,第j个象素的指针 
			// 注意此处宽度和高度是新DIB的宽度和高度 
			lpDst = (char *)lpNewDIBBits + lNewLineBytes * (lNewHeight - 1 - i) + j; 
			 
			// 计算该象素在源DIB中的坐标 
			i0 = (LONG) (i / fYZoomRatio + 0.5); 
			j0 = (LONG) (j / fXZoomRatio + 0.5); 
			 
			// 判断是否在源图范围内 
			if( (j0 >= 0) && (j0 < lWidth) && (i0 >= 0) && (i0 < lHeight)) 
			{ 
				 
				// 指向源DIB第i0行,第j0个象素的指针 
				lpSrc = (char *)lpDIBBits + lLineBytes * (lHeight - 1 - i0) + j0; 
				 
				// 复制象素 
				*lpDst = *lpSrc; 
			} 
			else 
			{ 
				// 对于源图中没有的象素,直接赋值为255 
				* ((unsigned char*)lpDst) = 255; 
			} 
			 
		} 
		 
	} 
	 
	// 返回 
	return hDIB; 
} 
 
 
 
HDIB  Template(HDIB hDIB,double * tem ,int tem_w,int tem_h,double xishu) 
{ 
 
    //统计中间值 
    double sum; 
 
    //指向图像起始位置的指针 
    BYTE *lpDIB=(BYTE*)::GlobalLock((HGLOBAL) hDIB); 
 
	//指向象素起始位置的指针 
	BYTE *pScrBuff =(BYTE*)::FindDIBBits((char*)lpDIB); 
    
	//获取图像的颜色信息 
    int numColors=(int) ::DIBNumColors((char *)lpDIB); 
 
    //如果图像不是256色返回 
     if (numColors!=256)  
	 {    
        //解除锁定 
	  	::GlobalUnlock((HGLOBAL) hDIB); 
 
		//返回 
		return(hDIB); 
	 } 
     
    //将指向图像象素起始位置的指针,赋值给指针变量 
    BYTE* oldbuf = pScrBuff; 
 
    //循环变量 
    int i,j,m,n; 
 
	int w, h, dw; 
 
	//获取图像的宽度 
	w = (int) ::DIBWidth((char *)lpDIB); 
	 
	//获取图像的高度 
	h = (int) ::DIBHeight((char *)lpDIB); 
	 
	//计算图像每行的字节数 
	dw = (w+3)/4*4;       
	 
	//建立一个和原图像大小相同的25色灰度位图 
    HDIB newhDIB=NewDIB(w,h,8);   
     
	//指向新的位图的指针 
	BYTE *newlpDIB=(BYTE*)::GlobalLock((HGLOBAL) newhDIB); 
 
	//指向新的位图的象素起始位置的指针  
    BYTE *destBuf = (BYTE*)FindDIBBits((char *)newlpDIB); 
     
   //将指向新图像象素起始位置的指针,赋值给指针变量 
    BYTE *newbuf=destBuf;  
	 
	//对图像进行扫描 
    
	//行  
    for(i=0;i(w-(tem_w+1)/2) || i<((tem_h-1)/2) || i>(h-(tem_h+1)/2) ) 
	      *(newbuf+i*dw+j)=*(oldbuf+i*dw+j); 
		  
         //对于其他的象素进行模板操作 
		 else  
         {  
 
          //将点(i,j)点作为模板的中心 
          for(m=i-((tem_h-1)/2);m<=i+((tem_h-1)/2);m++) 
          { 
		     for(n=j-((tem_w-1)/2);n<=j+((tem_w-1)/2);n++) 
		     
             //将以点(i,j)为中心,与模板大小相同的范围内的象素与模板对用位置的系数 
			 //进行相乘并线形叠加 
		     sum+=*(oldbuf+m*dw+n)* tem[(m-i+((tem_h-1)/2))*tem_w+n-j+((tem_w-1)/2)]; 
			 
		  } 
 
           
		  //将结果乘上总的模板系数 
          sum=(int)sum*xishu; 
 
		  //计算绝对值 
		  sum = fabs(sum); 
		  
		  //如果小于0,强制赋值为0 
          if(sum<0)      
          sum=0; 
 
		  //如果大于255,强制赋值为255 
          if(sum>255) 
		  sum=255; 
 
		  //将计算的结果放到新的位图的相应位置 
	      *(newbuf+i*dw+j)=sum; 
		 } 
	   } 
	}  
    
	//解除锁定 
	::GlobalUnlock((HGLOBAL)hDIB); 
     
	//返回新的位图的句柄 
    return(newhDIB); 
} 
void ThinnerRosenfeld(void *image, unsigned long lx, unsigned long ly) 
{ 
    char *f, *g; 
    char n[10]; 
    char a[5] = {0, -1, 1, 0, 0}; 
    char b[5] = {0, 0, 0, 1, -1}; 
    char nrnd, cond, n48, n26, n24, n46, n68, n82, n123, n345, n567, n781; 
    short k, shori; 
    unsigned long i, j; 
    long ii, jj, kk, kk1, kk2, kk3, size; 
    size = (long)lx * (long)ly; 
 
    g = (char *)malloc(size); 
    if(g==NULL) 
    { 
        printf("error in alocating mmeory!\n"); 
        return; 
    } 
 
    f = (char *)image; 
    for(kk=0l; kk0) 
                    { 
                        if(!cond) 
                            continue; 
                        g[kk] = 0; 
                        shori = 1; 
                        continue; 
                    } 
 
                    if(n[6]==1 && n48==0 && n123>0) 
                    { 
                        if(!cond) 
                            continue; 
                        g[kk] = 0; 
                        shori = 1; 
                        continue; 
                    } 
 
                    if(n[8]==1 && n26==0 && n345>0) 
                    { 
                        if(!cond) 
                            continue; 
                        g[kk] = 0; 
                        shori = 1; 
                        continue; 
                    } 
 
                    if(n[4]==1 && n26==0 && n781>0) 
                    { 
                        if(!cond) 
                            continue; 
                        g[kk] = 0; 
                        shori = 1; 
                        continue; 
                    } 
 
                    if(n[5]==1 && n46==0) 
                    { 
                        if(!cond) 
                            continue; 
                        g[kk] = 0; 
                        shori = 1; 
                        continue; 
                    } 
 
                    if(n[7]==1 && n68==0) 
                    { 
                        if(!cond) 
                            continue; 
                        g[kk] = 0; 
                        shori = 1; 
                        continue; 
                    } 
 
                    if(n[1]==1 && n82==0) 
                    { 
                        if(!cond) 
                            continue; 
                        g[kk] = 0; 
                        shori = 1; 
                        continue; 
                    } 
 
                    if(n[3]==1 && n24==0) 
                    { 
                        if(!cond) 
                            continue; 
                        g[kk] = 0; 
                        shori = 1; 
                        continue; 
                    } 
 
                    cond = 1; 
                    if(!cond) 
                        continue; 
                    g[kk] = 0; 
                    shori = 1; 
                } 
            } 
 
            for(i=0; i(w-(tem_w+1)/2) || i<((tem_h-1)/2) || i>(h-(tem_h+1)/2) ) 
					*(newbuf+i*dw+j)=*(oldbuf+i*dw+j); 
		  
         //对于其他的象素进行模板操作 
					else  
						{  
 
          //将点(i,j)点作为模板的中心 
							for(m=i-((tem_h-1)/2);m<=i+((tem_h-1)/2);m++) 
							{ 
								for(n=j-((tem_w-1)/2);n<=j+((tem_w-1)/2);n++) 
		     
             //将以点(i,j)为中心,与模板大小相同的范围内的象素与模板对用位置的系数 
			 //进行相乘并线形叠加 
									sum+=*(oldbuf+m*dw+n)* tem[k*9+(m-i+((tem_h-1)/2))*tem_w+n-j+((tem_w-1)/2)]; 
			 
							} 
         
		  //将结果乘上总的模板系数 
				          sum=(int)sum*xishu; 
 
		  //计算绝对值 
							sum = fabs(sum); 
		 		  //如果小于0,强制赋值为0 
							 if(sum<0)      
							sum=0; 
 
		  //如果大于255,强制赋值为255 
							if(sum>255) 
							sum=255; 
							if(sum>=temp) 
								temp=sum; 
					} 
		  //将计算的结果放到新的位图的相应位置 
	      *(newbuf+i*dw+j)=temp; 
		  temp=0; 
		 } 
	   } 
	}  
    
	//解除锁定 
	::GlobalUnlock((HGLOBAL)hDIB); 
     
	//返回新的位图的句柄 
    return(newhDIB); 
} 
 
 
 
 
 
 
 
 
 
 
 
 
 
BOOL WINAPI PaintDIB(HDC     hDC, 
					LPRECT  lpDCRect, 
					HDIB    hDIB, 
					LPRECT  lpDIBRect, 
					CPalette* pPal) 
{ 
	LPSTR    lpDIBHdr;            // Pointer to BITMAPINFOHEADER 
	LPSTR    lpDIBBits;           // Pointer to DIB bits 
	BOOL     bSuccess=FALSE;      // Success/fail flag 
	HPALETTE hPal=NULL;           // Our DIB's palette 
	HPALETTE hOldPal=NULL;        // Previous palette 
 
	/* Check for valid DIB handle */ 
	if (hDIB == NULL) 
		return FALSE; 
 
	/* Lock down the DIB, and get a pointer to the beginning of the bit 
	 *  buffer 
	 */ 
	lpDIBHdr  = (LPSTR) ::GlobalLock((HGLOBAL) hDIB); 
	lpDIBBits = ::FindDIBBits(lpDIBHdr); 
 
	// Get the DIB's palette, then select it into DC 
	if (pPal != NULL) 
	{ 
		hPal = (HPALETTE) pPal->m_hObject; 
 
		// Select as background since we have 
		// already realized in forground if needed 
		hOldPal = ::SelectPalette(hDC, hPal, TRUE); 
	} 
 
	/* Make sure to use the stretching mode best for color pictures */ 
	::SetStretchBltMode(hDC, COLORONCOLOR); 
 
	/* Determine whether to call StretchDIBits() or SetDIBitsToDevice() */ 
	if ((RECTWIDTH(lpDCRect)  == RECTWIDTH(lpDIBRect)) && 
	   (RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect))) 
		bSuccess = ::SetDIBitsToDevice(hDC,                    // hDC 
								   lpDCRect->left,             // DestX 
								   lpDCRect->top,              // DestY 
								   RECTWIDTH(lpDCRect),        // nDestWidth 
								   RECTHEIGHT(lpDCRect),       // nDestHeight 
								   lpDIBRect->left,            // SrcX 
								   (int)DIBHeight(lpDIBHdr) - 
									  lpDIBRect->top - 
									  RECTHEIGHT(lpDIBRect),   // SrcY 
								   0,                          // nStartScan 
								   (WORD)DIBHeight(lpDIBHdr),  // nNumScans 
								   lpDIBBits,                  // lpBits 
								   (LPBITMAPINFO)lpDIBHdr,     // lpBitsInfo 
								   DIB_RGB_COLORS);            // wUsage 
   else 
	  bSuccess = ::StretchDIBits(hDC,                          // hDC 
							   lpDCRect->left,                 // DestX 
							   lpDCRect->top,                  // DestY 
							   RECTWIDTH(lpDCRect),            // nDestWidth 
							   RECTHEIGHT(lpDCRect),           // nDestHeight 
							   lpDIBRect->left,                // SrcX 
							   lpDIBRect->top,                 // SrcY 
							   RECTWIDTH(lpDIBRect),           // wSrcWidth 
							   RECTHEIGHT(lpDIBRect),          // wSrcHeight 
							   lpDIBBits,                      // lpBits 
							   (LPBITMAPINFO)lpDIBHdr,         // lpBitsInfo 
							   DIB_RGB_COLORS,                 // wUsage 
							   SRCCOPY);                       // dwROP 
 
   ::GlobalUnlock((HGLOBAL) hDIB); 
 
	/* Reselect old palette */ 
	if (hOldPal != NULL) 
	{ 
		::SelectPalette(hDC, hOldPal, TRUE); 
	} 
 
   return bSuccess; 
} 
 
/************************************************************************* 
 * 
 * CreateDIBPalette() 
 * 
 * Parameter: 
 * 
 * HDIB hDIB        - 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). 
 * 
 ************************************************************************/ 
 
 
BOOL WINAPI CreateDIBPalette(HDIB hDIB, CPalette* pPal) 
{ 
	LPLOGPALETTE lpPal;      // pointer to a logical palette 
	HANDLE hLogPal;          // handle to a logical palette 
	HPALETTE hPal = NULL;    // handle to a palette 
	int i;                   // loop index 
	WORD wNumColors;         // number of colors in color table 
	LPSTR lpbi;              // pointer to packed-DIB 
	LPBITMAPINFO lpbmi;      // pointer to BITMAPINFO structure (Win3.0) 
	LPBITMAPCOREINFO lpbmc;  // pointer to BITMAPCOREINFO structure (old) 
	BOOL bWinStyleDIB;       // flag which signifies whether this is a Win3.0 DIB 
	BOOL bResult = FALSE; 
 
	/* if handle to DIB is invalid, return FALSE */ 
 
	if (hDIB == NULL) 
	  return FALSE; 
 
   lpbi = (LPSTR) ::GlobalLock((HGLOBAL) hDIB); 
 
   /* get pointer to BITMAPINFO (Win 3.0) */ 
   lpbmi = (LPBITMAPINFO)lpbi; 
 
   /* get pointer to BITMAPCOREINFO (old 1.x) */ 
   lpbmc = (LPBITMAPCOREINFO)lpbi; 
 
   /* get the number of colors in the DIB */ 
   wNumColors = ::DIBNumColors(lpbi); 
 
   if (wNumColors != 0) 
   { 
		/* 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 == 0) 
		{ 
			::GlobalUnlock((HGLOBAL) hDIB); 
			return FALSE; 
		} 
 
		lpPal = (LPLOGPALETTE) ::GlobalLock((HGLOBAL) hLogPal); 
 
		/* set version and number of palette entries */ 
		lpPal->palVersion = PALVERSION; 
		lpPal->palNumEntries = (WORD)wNumColors; 
 
		/* is this a Win 3.0 DIB? */ 
		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; 
			} 
		} 
 
		/* create the palette and get handle to it */ 
		bResult = pPal->CreatePalette(lpPal); 
		::GlobalUnlock((HGLOBAL) hLogPal); 
		::GlobalFree((HGLOBAL) hLogPal); 
	} 
 
	::GlobalUnlock((HGLOBAL) hDIB); 
 
	return bResult; 
} 
 
/************************************************************************* 
 * 
 * FindDIBBits() 
 * 
 * Parameter: 
 * 
 * LPSTR lpbi       - pointer to packed-DIB memory block 
 * 
 * Return Value: 
 * 
 * LPSTR            - pointer to the DIB bits 
 * 
 * Description: 
 * 
 * This function calculates the address of the DIB's bits and returns a 
 * pointer to the DIB bits. 
 * 
 ************************************************************************/ 
 
 
LPSTR WINAPI FindDIBBits(LPSTR lpbi) 
{ 
	return (lpbi + *(LPDWORD)lpbi + ::PaletteSize(lpbi)); 
} 
 
 
/************************************************************************* 
 * 
 * DIBWidth() 
 * 
 * Parameter: 
 * 
 * LPSTR lpbi       - pointer to packed-DIB memory block 
 * 
 * Return Value: 
 * 
 * DWORD            - width of the DIB 
 * 
 * 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. 
 * 
 ************************************************************************/ 
 
 
DWORD WINAPI DIBWidth(LPSTR lpDIB) 
{ 
	LPBITMAPINFOHEADER lpbmi;  // pointer to a Win 3.0-style DIB 
	LPBITMAPCOREHEADER lpbmc;  // pointer to an other-style DIB 
 
	/* point to the header (whether Win 3.0 and old) */ 
 
	lpbmi = (LPBITMAPINFOHEADER)lpDIB; 
	lpbmc = (LPBITMAPCOREHEADER)lpDIB; 
 
	/* return the DIB width if it is a Win 3.0 DIB */ 
	if (IS_WIN30_DIB(lpDIB)) 
		return lpbmi->biWidth; 
	else  /* it is an other-style DIB, so return its width */ 
		return (DWORD)lpbmc->bcWidth; 
} 
 
 
/************************************************************************* 
 * 
 * DIBHeight() 
 * 
 * Parameter: 
 * 
 * LPSTR lpbi       - pointer to packed-DIB memory block 
 * 
 * Return Value: 
 * 
 * DWORD            - height of the DIB 
 * 
 * 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. 
 * 
 ************************************************************************/ 
 
 
DWORD WINAPI DIBHeight(LPSTR lpDIB) 
{ 
	LPBITMAPINFOHEADER lpbmi;  // pointer to a Win 3.0-style DIB 
	LPBITMAPCOREHEADER lpbmc;  // pointer to an other-style DIB 
 
	/* point to the header (whether old or Win 3.0 */ 
 
	lpbmi = (LPBITMAPINFOHEADER)lpDIB; 
	lpbmc = (LPBITMAPCOREHEADER)lpDIB; 
 
	/* return the DIB height if it is a Win 3.0 DIB */ 
	if (IS_WIN30_DIB(lpDIB)) 
		return lpbmi->biHeight; 
	else  /* it is an other-style DIB, so return its height */ 
		return (DWORD)lpbmc->bcHeight; 
} 
 
 
/************************************************************************* 
 * 
 * PaletteSize() 
 * 
 * Parameter: 
 * 
 * LPSTR lpbi       - pointer to packed-DIB memory block 
 * 
 * Return Value: 
 * 
 * WORD             - size of the color palette of the DIB 
 * 
 * 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). 
 * 
 ************************************************************************/ 
 
 
WORD WINAPI PaletteSize(LPSTR lpbi) 
{ 
   /* calculate the size required by the palette */ 
   if (IS_WIN30_DIB (lpbi)) 
	  return (WORD)(::DIBNumColors(lpbi) * sizeof(RGBQUAD)); 
   else 
	  return (WORD)(::DIBNumColors(lpbi) * sizeof(RGBTRIPLE)); 
} 
 
 
/************************************************************************* 
 * 
 * DIBNumColors() 
 * 
 * Parameter: 
 * 
 * LPSTR lpbi       - pointer to packed-DIB memory block 
 * 
 * Return Value: 
 * 
 * WORD             - number of colors in the color table 
 * 
 * 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. 
 * 
 ************************************************************************/ 
 
 
WORD WINAPI 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; 
	} 
} 
 
 
////////////////////////////////////////////////////////////////////////// 
//// Clipboard support 
 
//--------------------------------------------------------------------- 
// 
// Function:   CopyHandle (from SDK DibView sample clipbrd.c) 
// 
// Purpose:    Makes a copy of the given global memory block.  Returns 
//             a handle to the new memory block (NULL on error). 
// 
//             Routine stolen verbatim out of ShowDIB. 
// 
// Parms:      h == Handle to global memory to duplicate. 
// 
// Returns:    Handle to new global memory block. 
// 
//--------------------------------------------------------------------- 
 
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; 
} 
void WINAPI ConvertShort(unsigned short *array, long length) 
{ 
   unsigned long b1, b2; 
   unsigned char *ptr; 
 
   ptr = (unsigned char *)array; 
   while (length--) { 
      b1 = *ptr++; 
      b2 = *ptr++; 
      *array++ = (unsigned short)((b1 << 8) | (b2)); 
   } 
} 
 
void WINAPI ConvertLong(unsigned long  *array, long length) 
{ 
   unsigned long b1, b2, b3, b4; 
   unsigned char *ptr; 
 
   ptr = (unsigned char *)array; 
   while (length--) { 
      b1 = *ptr++; 
      b2 = *ptr++; 
      b3 = *ptr++; 
      b4 = *ptr++; 
      *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4); 
   } 
} 
 
 
/************************************************************************* 
 * 
 * SaveDIB() 
 * 
 * Saves the specified DIB into the specified CFile.  The CFile 
 * is opened and closed by the caller. 
 * 
 * Parameters: 
 * 
 * HDIB hDib - Handle to the dib to save 
 * 
 * CFile& file - open CFile used to save DIB 
 * 
 * Return value: TRUE if successful, else FALSE or CFileException 
 * 
 *************************************************************************/ 
 
 
BOOL WINAPI SaveDIB(HDIB hDib, CFile& file) 
{ 
	BITMAPFILEHEADER bmfHdr; // Header for Bitmap file 
	LPBITMAPINFOHEADER lpBI;   // Pointer to DIB info structure 
	DWORD dwDIBSize; 
 
	if (hDib == NULL) 
		return FALSE; 
 
	/* 
	 * Get a pointer to the DIB memory, the first of which contains 
	 * a BITMAPINFO structure 
	 */ 
	lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib); 
	if (lpBI == NULL) 
		return FALSE; 
 
	if (!IS_WIN30_DIB(lpBI)) 
	{ 
		::GlobalUnlock((HGLOBAL) 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); 
#ifdef _MAC 
	ByteSwapHeader(&bmfHdr); 
 
	// First swap the size field 
	*((LPDWORD)lpBI) = SWAPLONG(*((LPDWORD)lpBI)); 
 
	// Now swap the rest of the structure (we don't save < Win30 files) 
	ByteSwapInfo((LPSTR)lpBI, TRUE); 
#endif 
 
	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) 
	{ 
#ifdef _MAC 
		// Swap everything back 
		*((LPDWORD)lpBI) = SWAPLONG(*((LPDWORD)lpBI)); 
		ByteSwapInfo((LPSTR)lpBI, TRUE); 
#endif 
		::GlobalUnlock((HGLOBAL) hDib); 
		THROW_LAST(); 
	} 
	END_CATCH 
 
#ifdef _MAC 
	// Swap everything back 
	*((LPDWORD)lpBI) = SWAPLONG(*((LPDWORD)lpBI)); 
	ByteSwapInfo((LPSTR)lpBI, TRUE); 
#endif 
 
	::GlobalUnlock((HGLOBAL) hDib); 
	return TRUE; 
} 
 
 
/************************************************************************* 
 
  Function:  ReadDIBFile (CFile&) 
 
   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. 
 
*************************************************************************/ 
 
 
HDIB WINAPI ReadDIBFile(CFile& file) 
{ 
	BITMAPFILEHEADER bmfHeader; 
	DWORD dwBitsSize; 
	HDIB hDIB; 
	LPSTR pDIB; 
 
	/* 
	 * get length of DIB in bytes for use when reading 
	 */ 
 
	dwBitsSize = file.GetLength(); 
 
	/* 
	 * Go read the DIB file header and check if it's valid. 
	 */ 
	if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader)) 
		return NULL; 
 
#ifdef _MAC 
	ByteSwapHeader(&bmfHeader); 
#endif 
	if (bmfHeader.bfType != DIB_HEADER_MARKER) 
		return NULL; 
 
	/* 
	 * Allocate memory for DIB 
	 */ 
	hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize); 
	if (hDIB == 0) 
	{ 
		return NULL; 
	} 
	pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB); 
 
	/* 
	 * Go read the bits. 
	 */ 
	if (file.ReadHuge(pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER)) != 
		dwBitsSize - sizeof(BITMAPFILEHEADER) ) 
	{ 
		::GlobalUnlock((HGLOBAL) hDIB); 
		::GlobalFree((HGLOBAL) hDIB); 
		return NULL; 
	} 
#ifdef _MAC 
	// First swap the size field 
	*((LPDWORD)pDIB) = SWAPLONG(*((LPDWORD)pDIB)); 
 
	// Now swap the rest of the structure 
	ByteSwapInfo(pDIB, IS_WIN30_DIB(pDIB)); 
#endif 
	::GlobalUnlock((HGLOBAL) hDIB); 
	return hDIB; 
} 
//  add Nov.27,1999 
HDIB WINAPI NewDIB(long width, long height,unsigned short biBitCount) // add "biBitCount" by hchen Jan 25,00 
{ 
	long dwindth = (width*biBitCount/8+3)/4*4; // align 4 bytes 
	WORD color_num; 
	switch(biBitCount) 
	{ 
		case 1: 
			color_num=2; 
			break; 
 
		case 4: 
			color_num=16; 
			break; 
		case 8: 
			color_num=256; 
			break; 
		default: 
			color_num=0; 
			break; 
	} 
 
	long dwBitsSize = dwindth *height + 40 + color_num*4;// 40 LPBIMHEAD 
 
	LPSTR pDIB; 
	HDIB hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize); 
	if (hDIB == 0) 
	{ 
		return NULL; 
	} 
	pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB); 
	 
	LPBITMAPINFO lpmf = (LPBITMAPINFO)pDIB; 
	lpmf->bmiHeader.biSize = 40;//40 
	lpmf->bmiHeader.biWidth = width; //i_info.width; 
    lpmf->bmiHeader.biHeight = height; 
    lpmf->bmiHeader.biPlanes = 1; 
	lpmf->bmiHeader.biBitCount = biBitCount;// 24 
	lpmf->bmiHeader.biCompression = 0; 
    lpmf->bmiHeader.biSizeImage = dwindth *height; 
	lpmf->bmiHeader.biXPelsPerMeter = 2925; 
    lpmf->bmiHeader.biYPelsPerMeter = 2925; 
    lpmf->bmiHeader.biClrUsed = 0;  
	lpmf->bmiHeader.biClrImportant= 0; 	 
 
	if(color_num!=0) 
	{ 
		for(int i=0;ibmiColors[i].rgbRed =(BYTE)i; 
			lpmf->bmiColors[i].rgbGreen =(BYTE)i; 
			lpmf->bmiColors[i].rgbBlue =(BYTE)i; 
		} 
	} 
 
	::GlobalUnlock((HGLOBAL) hDIB); 
	 
	return hDIB; 
} 
 
#ifdef _MAC 
void ByteSwapHeader(BITMAPFILEHEADER* bmfHeader) 
{ 
	bmfHeader->bfType = SWAPWORD(bmfHeader->bfType); 
	bmfHeader->bfSize = SWAPLONG(bmfHeader->bfSize); 
	bmfHeader->bfOffBits = SWAPLONG(bmfHeader->bfOffBits); 
} 
 
 
void ByteSwapInfo(LPSTR lpHeader, BOOL fWin30Header) 
{ 
	// Note this doesn't swap the bcSize/biSize field.  It assumes that the 
	// size field was swapped during read or while setting the fWin30Header 
	// flag. 
 
	if (fWin30Header) 
	{ 
		LPBITMAPINFOHEADER lpBMIH = &(LPBITMAPINFO(lpHeader)->bmiHeader); 
 
		//lpBMIH->biSize = SWAPLONG(lpBMIH->biSize); 
		lpBMIH->biWidth = SWAPLONG(lpBMIH->biWidth); 
		lpBMIH->biHeight = SWAPLONG(lpBMIH->biHeight); 
		lpBMIH->biPlanes = SWAPWORD(lpBMIH->biPlanes); 
		lpBMIH->biBitCount = SWAPWORD(lpBMIH->biBitCount); 
		lpBMIH->biCompression = SWAPLONG(lpBMIH->biCompression); 
		lpBMIH->biSizeImage = SWAPLONG(lpBMIH->biSizeImage); 
		lpBMIH->biXPelsPerMeter = SWAPLONG(lpBMIH->biXPelsPerMeter); 
		lpBMIH->biYPelsPerMeter = SWAPLONG(lpBMIH->biYPelsPerMeter); 
		lpBMIH->biClrUsed = SWAPLONG(lpBMIH->biClrUsed); 
		lpBMIH->biClrImportant = SWAPLONG(lpBMIH->biClrImportant); 
	} 
	else 
	{ 
		LPBITMAPCOREHEADER lpBMCH = &(LPBITMAPCOREINFO(lpHeader)->bmciHeader); 
 
		lpBMCH->bcWidth = SWAPWORD(lpBMCH->bcWidth); 
		lpBMCH->bcHeight = SWAPWORD(lpBMCH->bcHeight); 
		lpBMCH->bcPlanes = SWAPWORD(lpBMCH->bcPlanes); 
		lpBMCH->bcBitCount = SWAPWORD(lpBMCH->bcBitCount); 
	} 
} 
 
 
 
 
 
 
 
 
 
 
 
#endif