www.pudn.com > 3AdaBoost.rar > Image.cpp, change:2005-02-24,size:53450b


 
 
#include "stdafx.h" 
#include "math.h" 
 
#include "image.h" 
#include "globalfunc.h" 
 
#include <math.h>  // for sqrt() 
#include <windowsx.h>  // for GlobalAllocPtr 
 
#define		MAXIMAGESIZE    (3 * 65536) // 
const int CImage::GREY=256; 
 
IMPLEMENT_SERIAL(CImage, CObject, 0) 
 
/////////////////////////////////////////////////////////////////// 
CImage::CImage(): m_bIsDIB(TRUE),m_dwLength(0L), 
m_pDib (NULL),m_pData(NULL) 
{ 
        m_pPal	=new CPalette; 
} 
 
/////////////////////////////////////////////////////////////////// 
CImage::CImage(const CImage& img)//copy constructor 
{ 
        m_bIsDIB=img.m_bIsDIB; 
        m_dwLength=img.m_dwLength; 
        m_pDib=0; 
        if(img.m_pDib){ 
                m_pDib=(BYTE*) GlobalAllocPtr(GHND, m_dwLength); 
                if(!m_pDib) 
                { 
                        AfxMessageBox("Unable to allocate DIB memory"); 
                        return; 
                } 
                memcpy(m_pDib,img.m_pDib,m_dwLength); 
                m_pData = (BYTE*) m_pDib + sizeof(BITMAPINFOHEADER) + 
                        sizeof(RGBQUAD) * img.NumColors(); 
        } 
        m_pPal=new CPalette; 
        CreateDIBPalette(); 
} 
 
/////////////////////////////////////////////////////////////////// 
 
/////////////////////////////////////////////// 
/*the constructor used to create a DIB of size 'size' 
with no initializing image data*/ 
CImage::CImage(CSize size,int NumColor,int Bits) 
{ 
        LPBITMAPINFOHEADER pBMIH; 
        m_dwLength = sizeof(BITMAPINFOHEADER) +  
                sizeof(RGBQUAD) * NumColor; 
        if (!AllocateMemory()) return; 
        DWORD dwBytes = Transform((WORD)size.cx); 
 
        m_dwLength += dwBytes * size.cy * Bits / 8; 
        if (!AllocateMemory(TRUE)){ 
                return; 
        } 
        pBMIH=BMInfoHdPtr(); 
        pBMIH->biSize = sizeof(BITMAPINFOHEADER); 
        pBMIH->biWidth = size.cx; 
        pBMIH->biHeight = size.cy; 
        pBMIH->biSizeImage = size.cx*size.cy; 
        pBMIH->biPlanes = 1; 
        pBMIH->biBitCount = Bits; // 1, 4, 8, or 24 
        pBMIH->biCompression = BI_RGB; 
        pBMIH->biXPelsPerMeter = 0; 
        pBMIH->biYPelsPerMeter = 0; 
        pBMIH->biClrUsed = 0; 
        pBMIH->biClrImportant = 0; 
        m_pData =  (BYTE*)(m_pDib + sizeof(BITMAPINFOHEADER) + 
                sizeof(RGBQUAD) * NumColor); 
        SetDIB(); 
        m_pPal=new CPalette; 
        CreateGreyPalette(); 
} 
 
/////////////////////////////////////////////////////////////////// 
//part copy constructor 
CImage& CImage::operator=(const CImage& img) 
{ 
        m_bIsDIB=img.m_bIsDIB; 
        m_dwLength=img.m_dwLength; 
        if(img.m_pDib){ 
                TRY	{ 
                        if(m_pDib){ 
                                m_pDib = (BYTE*) GlobalReAllocPtr(m_pDib, 
                                        m_dwLength, GHND); 
                        }else 
                        { 
                                m_pDib=(BYTE*) GlobalAllocPtr(GHND, m_dwLength); 
                        } 
                } 
                CATCH (CMemoryException, e) { 
                        AfxMessageBox("Unable to allocate DIB memory"); 
                        return *this; 
                } 
                END_CATCH 
 
                        memcpy(m_pDib,img.m_pDib,m_dwLength); 
                m_pData = (BYTE*)((BYTE*) m_pDib + sizeof(BITMAPINFOHEADER) + 
                        sizeof(RGBQUAD) * img.NumColors()); 
        }else 
        { 
                GlobalFree(m_pDib); 
                m_pDib=0; 
        } 
        if(m_pPal) delete m_pPal; 
        m_pPal=new CPalette; 
        CreateDIBPalette(); 
        return *this; 
} 
 
/////////////////////////////////////////////////////////////////// 
CImage::CImage(CDC* pDC, int nBt, BOOL bCompr):m_bIsDIB(TRUE) 
/* pDC is memory DC ptr	and  Cbitmap object has been selected into it  
nBt is color bits per pixel (default = 0) 
bCompr is compression (default = TRUE) 
*/ 
{ 
        // constructs a DIB from the contents of a bitmap 
        BITMAP bm; 
        int    nPaletteSize,wBits; 
        LPBITMAPINFOHEADER pBMIH; 
        LPBITMAPINFO pBMI; 
 
        CBitmap* pEmptyBitmap = new CBitmap; 
        pEmptyBitmap->CreateCompatibleBitmap(pDC, 0, 0); 
        CBitmap* pBitmap = (CBitmap*) (pDC->SelectObject(pEmptyBitmap)); 
        pBitmap->GetObject(sizeof(bm), &bm); 
        if ((nBt == 1) || (nBt == 4) || (nBt == 8) || (nBt == 24)) { 
                wBits = nBt; 
        } 
        else {   // nBt = 0 
                wBits = bm.bmPlanes * bm.bmBitsPixel; // color bits per pixel 
        } 
        if (wBits == 1) { 
                nPaletteSize = 2; 
        } 
        else { 
                if (wBits == 4) { 
                        nPaletteSize = 16; 
                } 
                else { 
                        if (wBits == 8) { 
                                nPaletteSize = 256; 
                        } 
                        else { 
                                nPaletteSize = 0; // no palette for 24-bit display 
                        }  
                } 
        } 
        // fills out row to 4-byte boundary 
        DWORD dwBytes = ((DWORD) bm.bmWidth * wBits) / 32; 
        if (((DWORD) bm.bmWidth * wBits) % 32) { 
                dwBytes ++; 
        } 
        dwBytes *= 4;//pixels per line 
 
        m_dwLength = sizeof(BITMAPINFOHEADER) +  
                sizeof(RGBQUAD) * nPaletteSize; 
        if (!AllocateMemory()) return; 
 
        pBMIH=BMInfoHdPtr(); 
        pBMIH->biSize = sizeof(BITMAPINFOHEADER); 
        pBMIH->biWidth = bm.bmWidth; 
        pBMIH->biHeight = bm.bmHeight; 
        pBMIH->biPlanes = 1; 
        pBMIH->biBitCount = wBits; // 1, 4, 8, or 24 
        if (bCompr && (wBits == 4)) { 
                pBMIH->biCompression = BI_RLE4; 
        } 
        else { 
                if (bCompr && (wBits == 8)) {  
                        pBMIH->biCompression = BI_RLE8; 
                } 
                else { 
                        pBMIH->biCompression = BI_RGB; 
                }  
        } 
        pBMIH->biSizeImage = 0; 
        pBMIH->biXPelsPerMeter = 0; 
        pBMIH->biYPelsPerMeter = 0; 
        pBMIH->biClrUsed = 0; 
        pBMIH->biClrImportant = 0; 
 
        // calls GetDIBits with null data pointer to get size of DIB 
        pBMI=BMInfoPtr(); 
        ::GetDIBits(pDC->GetSafeHdc(), (HBITMAP) pBitmap->GetSafeHandle(), 
                0, (WORD) bm.bmHeight, NULL, pBMI, DIB_RGB_COLORS); 
 
        if (pBMIH->biSizeImage == 0) {//pBMIH????orpBMI 
                m_dwLength += dwBytes * bm.bmHeight; 
                pBMIH->biCompression = BI_RGB; 
                // escape route for device drivers that don't do compression 
                TRACE("Can't do compression\n"); 
        } 
        else { 
                m_dwLength += pBMIH->biSizeImage; 
        } 
        if (!AllocateMemory(TRUE)) { 
                return; 
        } 
        pBMIH=BMInfoHdPtr(); 
        pBMI=BMInfoPtr(); 
        m_pData = (BYTE*) pBMIH + sizeof(BITMAPINFOHEADER) + 
                sizeof(RGBQUAD) * nPaletteSize; 
 
        // second GetDIBits call to make DIB 
        if (!::GetDIBits(pDC->GetSafeHdc(), (HBITMAP) 
                pBitmap->GetSafeHandle(), 0, (WORD) bm.bmHeight, m_pData, 
                pBMI, DIB_RGB_COLORS)) { 
                        m_dwLength = 0L; 
                } 
                delete pDC->SelectObject(pBitmap); // delete pEmptyBitmap 
                Dib(); 
                m_pPal=new CPalette; 
                CreateDIBPalette(); 
} 
 
/////////////////////////////////////////////////////////////////// 
CImage::CImage(CImage& img, float scale) 
{ 
        WORD scrw,scrh,destw,desth; 
        DWORD dwDIBHeadLength; 
 
        img.Data(); 
        m_bIsDIB = img.m_bIsDIB; 
 
        scrw  = img.Width(); 
        scrh  = img.Height(); 
        destw = (WORD) (scrw * scale); 
        desth = (WORD) (scrh * scale); 
 
        dwDIBHeadLength = sizeof(BITMAPINFOHEADER) +  
                sizeof(RGBQUAD) * img.NumColors(); 
        DWORD dwBytes = Transform(destw); 
        m_dwLength = dwDIBHeadLength + (DWORD) dwBytes * desth; 
 
        m_pDib = NULL; 
        if(img.m_pDib) 
        { 
                m_pDib=(BYTE*) GlobalAllocPtr(GHND, m_dwLength); 
                if(!m_pDib){ 
                        AfxMessageBox("Unable to allocate DIB memory"); 
                        return; 
                } 
                memcpy(m_pDib, img.m_pDib, dwDIBHeadLength); 
                m_pData = (BYTE*) m_pDib + sizeof(BITMAPINFOHEADER) + 
                        sizeof(RGBQUAD) * img.NumColors(); 
        } 
        //shrink the image 
        ResizeImage(img.m_pData, scrw, scrh, m_pData, destw, desth); 
 
        LPBITMAPINFOHEADER pBMIH; 
        pBMIH=BMInfoHdPtr(); 
        pBMIH->biWidth = destw; 
        pBMIH->biHeight = desth; 
 
        Dib();						img.Dib(); 
        m_pPal=new CPalette;		CreateDIBPalette();		 
} 
 
/////////////////////////////////////////////////////////////////// 
//before usere call this construction,  
//must guarentee img.Bits() == 8 
 
 
/////////////////////////////////////////////////////////////////// 
CImage::~CImage() 
{ 
        if(m_dwLength != 0L)  
                GlobalFreePtr(m_pDib);  // free the DIB memory 
        if(m_pPal) 
                delete m_pPal; 
} 
 
/////////////////////////////////////////////////////////////////// 
void CImage::Serialize(CArchive& ar) 
{ 
        ar.Flush(); 
        if (ar.IsStoring())  
        { 
                WriteToFile(ar.GetFile()); 
        } 
        else  
        { 
                ReadFromFile(ar.GetFile()); 
        } 
} 
 
/////////////////////////////////////////////////////////////////// 
BOOL CImage::WriteAsBMP(CFile* pFile) 
{ 
        Dib(); 
        BITMAPFILEHEADER bmfHdr; // Header for Bitmap file 
        LPBITMAPINFOHEADER pBMIH=BMInfoHdPtr();   // Pointer to DIB info structure 
 
        if (m_pDib == NULL) 
                return FALSE; 
 
        /* Fill in file type (first 2 bytes must be "BM" for a bitmap) */ 
        bmfHdr.bfType = 0x4d42;  // "BM" 
 
        // Calculate the file size by adding the DIB size to sizeof(BITMAPFILEHEADER) 
 
        bmfHdr.bfSize = m_dwLength + sizeof(BITMAPFILEHEADER); 
        bmfHdr.bfReserved1 = 0; 
        bmfHdr.bfReserved2 = 0; 
 
        bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + pBMIH->biSize 
                + NumColors()*sizeof(RGBQUAD); 
        WORD hdLength=sizeof(BITMAPINFOHEADER) 
                + NumColors()*sizeof(RGBQUAD); 
        TRY { 
                // Write the file header 
                pFile->Write((BYTE*)&bmfHdr, sizeof(BITMAPFILEHEADER)); 
                // Write the DIB header 
                pFile->Write(m_pDib, hdLength); 
                // Write the DIB bits 
                pFile->Write(m_pData, m_dwLength-hdLength); 
        } 
        CATCH (CFileException, e) { 
                AfxMessageBox("Write error--possible disk full condition"); 
                return FALSE; 
        } 
        END_CATCH 
                return TRUE; 
} 
 
/////////////////////////////////////////////////////////////////// 
/* The MakeBitmap() 
CDC* pDoc :    Device Context 
bmSize    :    Change the parameter and return it 
Function:      Replaces the DC's old existing bitmap  
with the new one construced from this DIB 
Return Value:  the old bitmap in DC 
*/ 
////////////////////////////////////////////////////////     
CBitmap* CImage::MakeBitmap(CDC* pDC, CSize& bmSize) 
{ 
        BITMAP bm; 
        DWORD  dwFore, dwBack; 
        LPBITMAPINFOHEADER pBMIH = BMInfoHdPtr(); 
        LPBITMAPINFO pBMI = BMInfoPtr(); 
        // checks to see whether DIB buffer is properly loaded 
        if (m_dwLength == 0L) { 
                bmSize.cx = bmSize.cy = 0; 
                return NULL; 
        } 
 
        // this code conditions the DC for mono or color 
        SetPalette(pDC); 
        int nPlanes = pDC->GetDeviceCaps(PLANES); 
        int nBitsPixel = pDC->GetDeviceCaps(BITSPIXEL); 
        CBitmap* pConfigBitmap = new CBitmap; 
        char bits[100]; 
        if (pBMIH->biBitCount == 1) { 
                pConfigBitmap->CreateBitmap(1, 1, 1, 1, bits); 
        } 
        else { 
                pConfigBitmap->CreateBitmap(1, 1, nPlanes, nBitsPixel, bits); 
        } 
        CBitmap* pOriginalBitmap = 
                (CBitmap*) pDC->SelectObject(pConfigBitmap); 
 
        // CreateDIBitmap "switches bits" for mono bitmaps, depending on colors, 
        //  so we'll fool it 
        if (GetMonoColors(dwFore, dwBack)) { 
                SetMonoColors(0L, 0xFFFFFFL); 
        } 
        //the following CreateDIBitmap() creates a DDB from this DIB     
        //#ifdef _WIN32 
        HBITMAP hBitmap = ::CreateDIBitmap(pDC->GetSafeHdc(), pBMIH, 
                CBM_INIT, (CONST BYTE*) m_pData, pBMI, DIB_RGB_COLORS); 
        //#else 
        //    HBITMAP hBitmap = ::CreateDIBitmap(pDC->GetSafeHdc(), pBMIH, 
        //            CBM_INIT, (BYTE*) m_pData, pBMI, DIB_RGB_COLORS); 
        //#endif 
        if (hBitmap == NULL) { 
                TRACE("null bitmap\n");   
                delete pDC->SelectObject(pOriginalBitmap); // delete config bitmap 
                return NULL; // untested error logic 
        } 
 
        SetMonoColors(dwFore, dwBack); 
 
        // Can't use CBitmap::FromHandle here because we need to 
        //  delete the object later 
        CBitmap* pBitmap = new CBitmap; 
        pBitmap->Attach(hBitmap); 
        pBitmap->GetObject(sizeof(bm), &bm); 
        bmSize.cx = bm.bmWidth; 
        bmSize.cy = bm.bmHeight; 
        delete pDC->SelectObject(pBitmap); // delete configuration bitmap 
        return pOriginalBitmap; 
} 
/////////////////////////////////////////////////////////////////// 
//create a DIBpalette according to the palette info in the inforhead of object 
BOOL CImage::CreateDIBPalette() 
{ 
        LPLOGPALETTE lpPal;      // pointer to a logical palette 
        LPBITMAPINFO pBMI = BMInfoPtr(); 
        int i;                   // loop index 
        WORD wNumColors;         // number of colors in color table 
        BOOL bResult=FALSE; 
 
        /* if handle to DIB is invalid, return FALSE */ 
 
        if (!m_pDib)  return FALSE; 
 
        /* get the number of colors in the DIB */ 
        Dib(); 
        wNumColors = NumColors(); 
        if (wNumColors != 0) 
        { 
                /* allocate memory block for logical palette */ 
                /* if not enough memory, clean up and return NULL */ 
 
                lpPal = (LPLOGPALETTE) GlobalAllocPtr(GHND, sizeof(LOGPALETTE) 
                        + sizeof(PALETTEENTRY) 
                        * wNumColors); 
                if (lpPal == 0) return FALSE; 
 
                /* set version and number of palette entries */ 
                lpPal->palVersion = 0x300; 
                lpPal->palNumEntries = wNumColors; 
 
                for (i = 0; i < (int)wNumColors; i++) 
                { 
                        lpPal->palPalEntry[i].peRed = pBMI->bmiColors[i].rgbRed; 
                        lpPal->palPalEntry[i].peGreen = pBMI->bmiColors[i].rgbGreen; 
                        lpPal->palPalEntry[i].peBlue = pBMI->bmiColors[i].rgbBlue; 
                        lpPal->palPalEntry[i].peFlags = 0; 
                } 
 
                /* create the palette and get handle to it */ 
                delete m_pPal; 
                m_pPal=new CPalette; 
                bResult = m_pPal->CreatePalette(lpPal); 
                GlobalFreePtr(lpPal); 
        } 
 
        return bResult; 
} 
/////////////////////////////////////////////////////////////////// 
BOOL CImage::CreateGreyPalette() 
{ 
        LPLOGPALETTE lpPal;      // pointer to a logical palette 
        LPBITMAPINFO pBMI = BMInfoPtr(); 
        HANDLE hLogPal;          // handle to a logical palette 
        int i;                   // loop index 
        WORD wNumColors=NumColors();         // number of colors in color table 
        BOOL bResult=FALSE; 
        /* 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) return FALSE; 
        lpPal = (LPLOGPALETTE) ::GlobalLock((HGLOBAL) hLogPal); 
 
        /* set version and number of palette entries */ 
        lpPal->palVersion = 0x300; 
        lpPal->palNumEntries = wNumColors; 
        //set the grey value of palette   
        for (i = 0; i < (int)wNumColors; i++) 
        { 
                lpPal->palPalEntry[i].peRed = i; 
                lpPal->palPalEntry[i].peGreen = i; 
                lpPal->palPalEntry[i].peBlue = i; 
                lpPal->palPalEntry[i].peFlags = 0; 
                pBMI->bmiColors[i].rgbRed=i; 
                pBMI->bmiColors[i].rgbGreen=i; 
                pBMI->bmiColors[i].rgbBlue=i; 
        } 
 
        /* create the palette and get handle to it */ 
        delete m_pPal; 
        m_pPal=new CPalette; 
        bResult = m_pPal->CreatePalette(lpPal); 
        ::GlobalUnlock((HGLOBAL) hLogPal); 
        ::GlobalFree((HGLOBAL) hLogPal); 
        return bResult; 
} 
/////////////////////////////////////////////////////////////////// 
//create a grey DIB  according to the color bmp  
//and creat a grey palette according to the  
//inforhead of  the color bmp 
BOOL CImage::CreateGreyDib() 
{ 
        BYTE	y[256]; 
        WORD	i, j, w, h;  
        DWORD	dwL; 
        BOOL	bResult = FALSE; 
        LPBITMAPINFO pBMI; 
 
        if ( !m_pDib )  		return FALSE; 
 
        w		= Width(); 
        h		= Height(); 
        dwL		= w * h; 
        pBMI	= BMInfoPtr(); 
 
        switch(Bits()) 
        { 
        case 8: 
                { 
                        Data(); 
                        for (i = 0; i < NumColors() ; i++) 
                        { 
                                y[i] = (BYTE)( float( pBMI->bmiColors[i] . rgbRed)  * 0.30 
                                        + float( pBMI->bmiColors[i] . rgbGreen)* 0.59 
                                        + float( pBMI->bmiColors[i] . rgbBlue) * 0.11); 
                                if(y[i] > 255)  
                                        y[i] = 255; 
                        } 
                        CreateGreyPalette(); 
                        for(DWORD d=0 ; d<dwL ; d++)  
                        { 
                                m_pData[d] = y[m_pData[d]]; 
                        } 
 
                        Dib(); 
                        return TRUE; 
                } 
        case 24: 
                { 
                        CImage	*pGreyImage; 
                        DWORD	t1, t2; 
                        BYTE	*pGreyData, *pColData; 
 
                        pGreyImage	= new CImage(CSize(w, h), 256, 8); 
                        pColData	= Data(); 
                        pGreyData	= pGreyImage -> Data(); 
 
                        for(i=0; i<h; i++) 
                        { 
                                t1 = DWORD(i) * w * 3; 
                                for(j=0; j<w; j++) 
                                { 
                                        t2 = t1 + 3 * j; 
                                        pGreyData [ i * w + j ] = BYTE( 
                                                (float)(pColData[ t2 ] * 0.11) 
                                                + (float)(pColData[t2+1] * 0.59) 
                                                + (float)(pColData[t2+2] * 0.30)); 
                                } 
                        } 
                        ImageClear(); 
                        *this = *pGreyImage; 
                        Dib(); 
                        delete pGreyImage; 
                        return TRUE; 
                } 
        default: 
                { 
                        AfxMessageBox("Only convert 8 bits or 24 bits image to grey image"); 
                        return FALSE; 
                } 
        } 
} 
/////////////////////////////////////////////////////////////////// 
BOOL CImage::Display(CDC* pDC, CPoint origin) const 
{ 
        // direct to device--bypass the GDI bitmap 
        LPBITMAPINFOHEADER pBMIH = BMInfoHdPtr(); 
        LPBITMAPINFO pBMI = BMInfoPtr(); 
        if (!m_pDib) { 
                return FALSE; // nothing to display 
        } 
        if (!::SetDIBitsToDevice(pDC->GetSafeHdc(), origin.x, origin.y, 
                (WORD) pBMIH->biWidth, (WORD) pBMIH->biHeight, 0, 0, 0, 
                (WORD) pBMIH->biHeight, m_pData, pBMI, 
                DIB_RGB_COLORS)) { 
                        return FALSE; 
                } 
                return TRUE; 
} 
 
/////////////////////////////////////////////////////////////////// 
BOOL CImage::Stretch(CDC* pDC, CPoint origin, CSize size) const 
{ 
        // direct to device--bypass the GDI bitmap 
        LPBITMAPINFOHEADER pBMIH = BMInfoHdPtr(); 
        LPBITMAPINFO pBMI = BMInfoPtr(); 
        if (!m_pDib) { 
                return FALSE; // nothing to display 
        } 
 
        ::SetStretchBltMode (pDC->GetSafeHdc(), COLORONCOLOR); 
 
        if (!::StretchDIBits(pDC->GetSafeHdc(), origin.x, origin.y, 
                size.cx, size.cy, 0, 0, (WORD) pBMIH->biWidth, 
                (WORD) pBMIH->biHeight, m_pData, pBMI, 
                DIB_RGB_COLORS, SRCCOPY)) { 
                        return FALSE; 
                } 
                return TRUE; 
} 
/////////////////////////////////////////////////////////////////// 
WORD CImage::Bits() const 
{ 
        ASSERT(m_pDib); 
        return ((LPBITMAPINFOHEADER)m_pDib)->biBitCount; 
} 
 
/////////////////////////////////////////////////////////////////// 
DWORD CImage::Length() const 
{ 
        return m_dwLength; 
} 
/////////////////////////////////////////////////////////////////// 
 
CSize CImage::Size() const 
{ 
        ASSERT(m_pDib); 
        LPBITMAPINFOHEADER pBMIH = BMInfoHdPtr(); 
        return CSize((int) pBMIH->biWidth, (int) pBMIH->biHeight); 
} 
/////////////////////////////////////////////////////////////////// 
 
WORD CImage::Height() const 
{ 
        ASSERT(m_pDib); 
        return (WORD)(((LPBITMAPINFOHEADER)m_pDib)->biHeight); 
} 
/////////////////////////////////////////////////////////////////// 
 
WORD CImage::Width() const 
{ 
        ASSERT(m_pDib); 
        return (WORD) (((LPBITMAPINFOHEADER)m_pDib)->biWidth); 
} 
/////////////////////////////////////////////////////////////////// 
//return the number of entries in the color pallete 
WORD CImage::NumColors() const 
{ 
        ASSERT(m_pDib); 
        LPBITMAPINFOHEADER pBMIH = BMInfoHdPtr(); 
        if(m_pDib==NULL) return NULL; 
        if(pBMIH->biClrUsed!=0) 
                return (WORD)pBMIH->biClrUsed; 
        switch(pBMIH->biBitCount) 
        { 
        case 1: 
                return 2; 
        case 4: 
                return 16; 
        case 8: 
                return 256; 
        default: 
                return 0; 
        } 
} 
/////////////////////////////////////////////////////////////////// 
LPBITMAPINFOHEADER CImage::BMInfoHdPtr() const 
{ 
        return (LPBITMAPINFOHEADER)m_pDib; 
} 
/////////////////////////////////////////////////////////////////// 
LPBITMAPINFO CImage::BMInfoPtr() const 
{ 
        return (LPBITMAPINFO)m_pDib; 
} 
/////////////////////////////////////////////////////////////////// 
RGBQUAD* CImage::BMColorTblPtr() const 
{ 
        return (RGBQUAD*)((int)m_pDib+sizeof(BITMAPINFOHEADER)); 
} 
/////////////////////////////////////////////////////////////////// 
void CImage::SetDIB(BOOL Flag) 
{ 
        if(Flag) m_bIsDIB=TRUE; 
        else m_bIsDIB=FALSE; 
} 
/////////////////////////////////////////////////////////////////// 
// To convert the non-DIB to DIB type 
BYTE* CImage::Dib() 
{ 
        if(!m_pDib) return NULL; 
        if(m_bIsDIB) return m_pData; 
 
        WORD		i, j; 
        BYTE		*p1, *p2; 
        WORD bpp	=	Bits(); 
        WORD bytepp =	bpp / 8; 
        WORD w		=	Width(); 
        WORD h		=	Height(); 
        long lBpl	=	w * bytepp; 
        WORD halfline = h / 2; 
 
        //reverse the order of scanning 
        //for(i=0 ; i<halfline-1 ; i++){/// Ms. Yao changed it! 
        BYTE temp; 
        p1 = m_pData; 
        p2 = m_pData + lBpl * h; 
        for(i=0 ; i<halfline; i++) 
        { 
                p2 -= lBpl; 
                for(j=0; j<lBpl; j++) 
                { 
                        temp  = p1[j]; 
                        p1[j] = p2[j]; 
                        p2[j] = temp; 
                } 
                p1 += lBpl; 
        } 
 
        if(((w * bpp) % 32)==0) 
        { 
                SetDIB(); 
                return m_pData; 
        } 
        /*otherwise, it is needed to pad data*/ 
        DWORD dwBNFOL = ByteNumForOneLine(w, bpp); 
        for(i=h-1; i>0; i--) 
        { 
                p1 = m_pData + i * dwBNFOL; 
                p2 = m_pData + i * lBpl; 
                memmove(p1, p2, lBpl); 
                memset(p1+lBpl, 0x00, (dwBNFOL - lBpl)); 
        } 
 
        SetDIB(); 
        return m_pData; 
} 
///////////////////////////////////////// 
//implement the reverse function of dib() 
BYTE* CImage::Data() 
{ 
        if(!m_pDib) return NULL; 
        if(!m_bIsDIB) return m_pData; 
 
        WORD	i,j; 
        BYTE	*p1, *p2; 
        WORD	bpp		= Bits();//bpp 
        WORD	Bytepp	= bpp / 8; 
        WORD	w		= Width(); 
        WORD	h		= Height(); 
        WORD	halfline= h/2; 
 
        LPBITMAPINFOHEADER pBMIH = BMInfoHdPtr( ); 
 
        if(pBMIH->biCompression!=BI_RGB) 
        { 
                AfxMessageBox("Con't process compressed image"); 
                return NULL; 
        } 
 
        if((w * bpp) % 32) 
        { 
                long	t		= w * Bytepp; 
                DWORD dwBNFOL	= ByteNumForOneLine(w, bpp); 
                p2 = p1 = m_pData; 
                for(i=0; i<h-1; i++) 
                { 
                        p1 += dwBNFOL; 
                        p2 += t; 
                        memmove(p2, p1, t); 
                } 
        } 
        /*/ 
        if((w * bpp) % 32) 
        { 
        long	lbpl	= w * Bytepp; 
        DWORD dwBNFOL	= ByteNumForOneLine(w, bpp); 
        for(i=0; i<h-1; i++) 
        { 
        p1 = m_pData + ( i + 1 ) * dwBNFOL; 
        p2 = m_pData + ( i + 1 ) * lbpl; 
        memmove(p2, p1, lbpl); 
        } 
        } 
        */ 
        /*for(i=0 ; i<halfline-1 ; i++)**Ms. Yao changed!**/ 
        long lBytePerLine	= w * Bytepp; 
        p1	= m_pData; 
        p2	= m_pData + h * lBytePerLine; 
        BYTE temp; 
        for(i = 0 ; i < halfline; i++) 
        { 
                p2 -= lBytePerLine; 
                for(j = 0; j < lBytePerLine; j++) 
                { 
                        temp  = p1[j]; 
                        p1[j] = p2[j]; 
                        p2[j] = temp; 
                } 
                p1 += lBytePerLine; 
        } 
 
        SetDIB(FALSE); 
        return m_pData; 
} 
/////////////////////////////////////////////////////////////////// 
CPalette* CImage::Palette() const 
{ 
        return m_pPal; 
} 
/////////////////////////////////////////////////////////////////// 
 
UINT CImage::SetPalette(CDC* pDC,BOOL bBackground) const 
{ 
        if(!m_pPal->m_hObject) return FALSE; 
        VERIFY(pDC->SelectPalette(m_pPal,bBackground)); 
        return(pDC->RealizePalette()); 
} 
/////////////////////////////////////////////////////////////////// 
void CImage::SetMonoColors(DWORD dwForeground, DWORD dwBackground) 
{ 
        if (Bits() != 1) { 
                return; 
        } 
        unsigned long far* pPalette = (unsigned long far*) 
                BMColorTblPtr(); 
        *pPalette = dwForeground; 
        *(++pPalette) = dwBackground; 
        return; 
} 
 
/////////////////////////////////////////////////////////////////// 
BOOL CImage::GetMonoColors(DWORD& dwForeground, DWORD& dwBackground) 
{ 
        if (Bits() != 1) { 
                return FALSE; 
        } 
        unsigned long far* pPalette = (unsigned long far*) 
                BMColorTblPtr(); 
        dwForeground = *pPalette; 
        dwBackground = *(++pPalette); 
        return TRUE; 
} 
 
/////////////////////////////////////////////////////////////////// 
BOOL CImage::AllocateMemory(BOOL bRealloc) // bRealloc default = FALSE 
{ 
        if (bRealloc) {   
                m_pDib = (BYTE*) GlobalReAllocPtr(m_pDib, 
                        m_dwLength, GHND); 
        } 
        else { 
                m_pDib = (BYTE*) GlobalAllocPtr(GHND, m_dwLength); 
        } 
        if (!m_pDib) { 
                AfxMessageBox("Unable to allocate DIB memory"); 
                m_dwLength = 0L; 
                return FALSE; 
        } 
        return TRUE; 
} 
/*Record of Modify 
*	Date		Operator	Modify			 
* 1999.4.9		S.S.G		if the width of the bitmap can not be inter-divided by 8 
*							We must alloc enough additional memory!! and some situations 
*							must be processed 
*/ 
BOOL CImage::ReadFromBMP(CFile * pFile) 
{ 
        BITMAPFILEHEADER bmfHdr; // Header for Bitmap file 
        BITMAPINFOHEADER bmhdr;	 //header for bitmap info 
        long   biWidth;     
        long   biHeight;  
 
        ASSERT(m_dwLength == 0L); // DIB must be empty 
 
        if ((pFile->Read((BYTE*)&bmfHdr, sizeof(bmfHdr)) != 
                sizeof(bmfHdr))) { 
                        AfxMessageBox("Read error"); 
                        return FALSE; 
                } 
                if (bmfHdr.bfType != 0x4d42) 
                { 
                        AfxMessageBox("Invalid bitmap file"); 
                        return FALSE; 
                } 
                //1999.4.9 added 
                if ((pFile->Read((BYTE*)&bmhdr, sizeof(bmhdr)) != 
                        sizeof(bmhdr))) { 
                                AfxMessageBox("Read error"); 
                                return FALSE; 
                        } 
                        if(bmhdr.biSize != sizeof(bmhdr)) 
                        { 
                                AfxMessageBox("Invalid bitmap file"); 
                                return FALSE; 
                        } 
                        if(bmhdr.biBitCount == 16 && bmhdr.biBitCount == 32) 
                        { 
                                AfxMessageBox("Sorry! Current version only support\n 8bpp and 24bpp BMP!"); 
                                return FALSE; 
                        } 
 
                        if(bmhdr.biCompression != BI_RGB ) 
                        { 
                                AfxMessageBox("Sorry! Current version do NOT support\n compressed BMP!"); 
                                return FALSE; 
                        } 
                        biWidth = bmhdr.biWidth; 
                        biHeight= abs(bmhdr.biHeight);  
                        DWORD dwBytes = ByteNumForOneLine(WORD(biWidth), bmhdr.biBitCount); 
                        //->| 
                        m_dwLength = pFile->GetLength(); 
                        m_dwLength -= sizeof(BITMAPFILEHEADER); 
                        /*1999.4.9 added the following line*/ 
                        //add the needed extent memory!!! 
                        m_dwLength += (dwBytes - (bmhdr.biBitCount / 8) * bmhdr.biWidth) * bmhdr.biHeight; 
 
                        if (!AllocateMemory()) { 
                                return FALSE;        
                        } 
 
                        pFile->Seek(sizeof(BITMAPFILEHEADER), CFile::begin); 
                        TRY { 
                                pFile->Read(m_pDib, m_dwLength); 
                        } 
                        CATCH (CFileException, e) { 
                                AfxMessageBox("Read error"); 
                                GlobalFreePtr(m_pDib);  // free the DIB memory 
                                return FALSE; 
                        } 
                        END_CATCH 
 
                                m_pData = (BYTE*) m_pDib + sizeof(BITMAPINFOHEADER) + 
                                sizeof(RGBQUAD) * NumColors(); 
                        CreateDIBPalette(); 
                        SetDIB();  
                        return TRUE; 
} 
 
BOOL CImage::ReadFromPGM(CFile * pFile) 
{ 
        // file assumed to be open 
        LPBITMAPINFOHEADER pBMIH; 
        char ch;	 
        WORD w, h, i=0, j=0; 
        char str[10]; 
        CString sfilehead; 
 
        ASSERT(m_dwLength == 0); 
 
        DWORD dwFileLength = pFile->GetLength(); 
        DWORD dwDataPos=0; 
        pFile->Seek(0,CFile::begin); 
        TRY { 
                pFile->Read(sfilehead.GetBuffer(100), 100); 
        } 
        CATCH (CFileException, e) { 
                AfxMessageBox("Read error"); 
                return FALSE; 
        } 
        END_CATCH 
 
                sfilehead.ReleaseBuffer(); 
        if(sfilehead == "")	{ 
                AfxMessageBox("Invalid PGM image file"); 
                return false; 
        } 
        if(sfilehead.GetAt(0) != 'P'||sfilehead.GetAt(1) != '5') { 
                AfxMessageBox("Invalid PGM image file"); 
                return false; 
        } 
 
        int tt = 0;	dwDataPos = 0; 
        while(tt != 4)//4: for YaleFaceBaseB, 3: for others 
        { 
                if(sfilehead.GetAt(dwDataPos) == '\n') 
                        tt++; 
                dwDataPos++; 
                if(dwDataPos > 100) 
                { 
                        AfxMessageBox("The format is wrong!"); 
                        return false; 
                } 
        } 
 
        dwFileLength -= dwDataPos; 
 
        i=0;	ch=sfilehead.GetAt(i++); 
        while(ch!='\n')  ch=sfilehead.GetAt(i++); 
        //for Yale FaceBaseB only 
        ch=sfilehead.GetAt(i++); 
        while(ch!='\n')  ch=sfilehead.GetAt(i++); 
 
        j=0;  	ch=sfilehead.GetAt(i++); 
        while(ch!=' ') 
        { str[j++]=ch; ch=sfilehead.GetAt(i++);} 
        str[j]='\0';	w=atoi(str); 
 
        j=0;	ch=sfilehead.GetAt(i++); 
        while(ch!='\n')  
        {str[j++]=ch;	ch=sfilehead.GetAt(i++);} 
        str[j]='\0';	h=atoi(str); 
 
        if( DWORD(w*h) > dwFileLength) 
        { 
                AfxMessageBox("w*h != DataLength, The image data is wrong!"); 
                return false; 
        } 
        //make the number of bytes in one line can be divided exactly by 4 
        DWORD dwBytes = Transform(w);//bytes per line 
 
        m_dwLength = DWORD(dwBytes * h) + sizeof(BITMAPINFOHEADER) 
                + sizeof(RGBQUAD) * 256; 
        if (!AllocateMemory()) { 
                AfxMessageBox("Allocmemory Error"); 
                return FALSE;} 
 
        pBMIH=BMInfoHdPtr(); 
        pBMIH->biSize = sizeof(BITMAPINFOHEADER); 
        pBMIH->biWidth = w; 
        pBMIH->biHeight = h; 
        pBMIH->biPlanes = 1; 
        pBMIH->biBitCount = 8; 
        pBMIH->biCompression = BI_RGB; 
        pBMIH->biSizeImage = 0; 
        pBMIH->biXPelsPerMeter = 0; 
        pBMIH->biYPelsPerMeter = 0; 
        pBMIH->biClrUsed = 0; 
        pBMIH->biClrImportant = 0; 
        m_pData = (BYTE*) m_pDib + sizeof(BITMAPINFOHEADER) + 
                sizeof(RGBQUAD) * NumColors(); 
        pFile->Seek(dwDataPos/*+1 980518 modified!!*/,CFile::begin); 
        long dd; 
        TRY { 
                dd = pFile->Read(m_pData, DWORD(w * h)); 
                //pFile->Read(m_pData, dwFileLength); 
        } 
        CATCH (CFileException, e) { 
                AfxMessageBox("Read error"); 
                GlobalFreePtr(m_pDib);  // free the DIB memory 
                return FALSE;	} 
        END_CATCH 
 
                CreateGreyPalette(); 
        SetDIB(FALSE); 
        Dib();    
        return TRUE; 
} 
 
BOOL CImage::WriteAsPGM(CFile * pFile) 
{ 
        WORD w, h; 
        char cWidth[5]; 
        char cHeight[5]; 
        char* PgmHead = new char[30]; 
        Data(); 
 
        strcpy(PgmHead, "P5\n"); 
        if (m_pDib == NULL) 
                return FALSE; 
        if(Bits() != 8)  
        { 
                AfxMessageBox("It is not 8-greylevel image!");		 
                return false;	} 
 
        w = Width();		h = Height(); 
        itoa(w,cWidth,10);	itoa(h,cHeight,10); 
        strcat(PgmHead,cWidth);		strcat(PgmHead," "); 
        strcat(PgmHead,cHeight);	strcat(PgmHead,"\n255\n"); 
 
        // Calculate the file size by adding the DIB size to sizeof(BITMAPFILEHEADER) 
 
        WORD hdLength = sizeof(BITMAPINFOHEADER) 
                + NumColors()*sizeof(RGBQUAD); 
        TRY { 
                pFile->Write(PgmHead,strlen(PgmHead)); 
                pFile->Write(m_pData, (long)w*h); 
        } 
        CATCH (CFileException, e) { 
                AfxMessageBox("Write error--possible disk full condition"); 
                return FALSE; 
        } 
        END_CATCH 
                Dib(); 
        delete PgmHead; 
        return TRUE; 
} 
 
BOOL CImage::WriteAsData(CFile* pFile) 
{ 
        WORD w = Width(); 
        WORD h = Height(); 
        BYTE* pData = Data(); 
        TRY  
        { 
                pFile->Write(pData, (long)w*h); 
        } 
        CATCH (CFileException, e)  
        { 
                AfxMessageBox("Write error--possible disk full condition"); 
                return FALSE; 
        } 
        END_CATCH 
                Dib(); 
        return TRUE; 
} 
 
BOOL CImage::ReadFromFile(CFile * pFile) 
{ 
        //if(ReadFromDAT(pFile)) 
        //	return TRUE; 
 
        BOOL	bReturn; 
        CString FileName=pFile->GetFilePath(); 
 
        int nPointPos=FileName.Find("."); 
        FileName.MakeLower(); 
        FileName=FileName.Mid(nPointPos+1); 
        bReturn = FALSE; 
 
        if(FileName=="bmp")	 
                return ReadFromBMP(pFile); 
        if(FileName=="pgm")   
                return ReadFromPGM(pFile); 
        if(FileName == "img") 
                return ReadFromIMG(pFile); 
        if(FileName == "dat") 
                return ReadFromDAT(pFile); 
        if(FileName == "raw") 
                return ReadFromDAT(pFile); 
        if(ReadFromBMP(pFile)) 
                return TRUE; 
        return FALSE; 
} 
 
BOOL CImage::ReadFromFile(CString filename) 
{ 
        CString	ext  = filename; 
        int nPointPos=ext.Find("."); 
        ext.MakeLower(); 
        ext=ext.Mid(nPointPos+1); 
        //if(ext == "jpg" || ext == "gif" ) 
        //	return ReadFromJPG(filename); 
 
        CFile* pFile = new CFile; 
        if(!pFile->Open(filename,CFile::modeRead)) 
        { 
                AfxMessageBox("In CImage::ReadFromFile(),Can not opent the file!"); 
                return false; 
        } 
 
        BOOL b = ReadFromFile(pFile); 
 
        pFile->Close(); 
        delete pFile; 
        return b; 
} 
 
BOOL	CImage::ReadFromJPG(CString filename) 
{ 
        return FALSE; 
} 
 
BOOL CImage::WriteToFile(CFile * pFile) 
{ 
        CString FileName=pFile->GetFileName(); 
        int nPointPos=FileName.Find("."); 
        FileName.MakeLower(); 
        FileName=FileName.Mid(nPointPos+1); 
 
        if(FileName=="bmp")	 
                return WriteAsBMP(pFile); 
        if(FileName=="pgm")   
                return WriteAsPGM(pFile); 
        if(FileName=="bin" || FileName=="dat" || FileName=="raw" ) 
                return WriteAsData(pFile); 
        if(FileName=="txt") 
        { 
                CString temp = pFile->GetFilePath(); 
                pFile -> Close(); 
                BOOL b = SaveAsText(temp, FALSE); 
                pFile -> Open(temp, CFile::modeWrite); 
                return b; 
        } 
 
        return WriteAsBMP(pFile); 
} 
 
BOOL CImage::WriteToFile(CString filename) 
{ 
        CFile* pFile = new CFile; 
        if(!pFile->Open(filename,CFile::modeWrite|CFile::modeCreate)) 
        { 
                AfxMessageBox("In CImage::WriteToFile(),Can not opent the file!"); 
                return false; 
        } 
 
        BOOL b = WriteToFile(pFile); 
 
        pFile->Close(); 
        delete pFile; 
        return b;	 
} 
 
void CImage::ImageClear() 
{ 
        if (m_pDib)  
                GlobalFreePtr(m_pDib);  // free the DIB memory 
        m_pDib     = NULL; 
        m_pData    = NULL; 
        m_bIsDIB   = TRUE; 
        m_dwLength = 0L;  
} 
 
DWORD CImage::Transform(WORD width) 
{ 
        DWORD dwBytes = (width * 8) / 32; 
        if ((width * 8) % 32) { 
                dwBytes ++; 
        } 
        dwBytes *= 4; //bytes per line	 
        return dwBytes; 
} 
 
BOOL CImage::ReadFromIMG(CFile* pFile) 
{ 
        int		bpp; 
        LPBITMAPINFOHEADER pBMIH; 
        DWORD dwFileLength = pFile->GetLength(); 
        WORD w,h; 
 
        pFile->Read((WORD* )&w,sizeof(WORD)); 
        pFile->Read((WORD* )&h,sizeof(WORD)); 
 
        dwFileLength -= 2 * sizeof(WORD); 
        bpp = int(dwFileLength / (w * h)); 
        if(bpp != 1 && bpp != 3)/* 8 or 24 */ 
        { 
                AfxMessageBox("Wrong Data!"); 
                return false; 
        } 
 
        DWORD dwBytes = Transform(w);//bytes per line 
 
        m_dwLength = DWORD(dwBytes * h * bpp) + sizeof(BITMAPINFOHEADER) 
                + sizeof(RGBQUAD) * 256; 
        if (!AllocateMemory()) { 
                AfxMessageBox("Allocmemory Error"); 
                return FALSE;} 
 
        pBMIH=BMInfoHdPtr(); 
        pBMIH->biSize = sizeof(BITMAPINFOHEADER); 
        pBMIH->biWidth = w; 
        pBMIH->biHeight = h; 
        pBMIH->biPlanes = 1; 
        pBMIH->biBitCount = 8 * bpp; 
        pBMIH->biCompression = BI_RGB; 
        pBMIH->biSizeImage = 0; 
        pBMIH->biXPelsPerMeter = 0; 
        pBMIH->biYPelsPerMeter = 0; 
        pBMIH->biClrUsed = 0; 
        pBMIH->biClrImportant = 0; 
        m_pData = (BYTE*) m_pDib + sizeof(BITMAPINFOHEADER) + 
                sizeof(RGBQUAD) * NumColors(); 
        CreateGreyPalette(); 
 
        TRY { 
                pFile->Read(m_pData, dwFileLength); 
        } 
        CATCH (CFileException, e) { 
                AfxMessageBox("Read error"); 
                GlobalFreePtr(m_pDib);  // free the DIB memory 
                return FALSE; 
        } 
        END_CATCH 
 
                SetDIB(true); 
        Dib(); 
        return TRUE; 
} 
 
BOOL CImage::ReadFromDAT(CFile* pFile) 
{ 
        LPBITMAPINFOHEADER pBMIH; 
        DWORD dwFileLength = pFile->GetLength(); 
        WORD w,h; 
        ///////just for MIT facebase!!! 
        w = 256; 
        h = 240; 
        //w = 128; 
        //h = 120; 
        //for bern faces 
        w = 512; 
        h = 342; 
 
        if(dwFileLength <= (DWORD)(w * h)) 
        { 
                AfxMessageBox("Wrong Data!"); 
                return false; 
        } 
 
        DWORD dwBytes = Transform(w);//bytes per line 
 
        m_dwLength = DWORD(dwBytes * h) + sizeof(BITMAPINFOHEADER) 
                + sizeof(RGBQUAD) * 256; 
        if (!AllocateMemory()) { 
                AfxMessageBox("Allocmemory Error"); 
                return FALSE;} 
 
        pBMIH=BMInfoHdPtr(); 
        pBMIH->biSize = sizeof(BITMAPINFOHEADER); 
        pBMIH->biWidth = w; 
        pBMIH->biHeight = h; 
        pBMIH->biPlanes = 1; 
        pBMIH->biBitCount = 8; 
        pBMIH->biCompression = BI_RGB; 
        pBMIH->biSizeImage = 0; 
        pBMIH->biXPelsPerMeter = 0; 
        pBMIH->biYPelsPerMeter = 0; 
        pBMIH->biClrUsed = 0; 
        pBMIH->biClrImportant = 0; 
        m_pData = (BYTE*) m_pDib + sizeof(BITMAPINFOHEADER) + 
                sizeof(RGBQUAD) * NumColors(); 
        CreateGreyPalette(); 
 
        //for bern faces 
        pFile->Seek(32L, CFile::begin); 
 
        TRY { 
                pFile->Read(m_pData, (long(w) * h)); 
        } 
        CATCH (CFileException, e) { 
                AfxMessageBox("Read error"); 
                GlobalFreePtr(m_pDib);  // free the DIB memory 
                return FALSE; 
        } 
        END_CATCH 
 
                SetDIB(false); 
        Dib(); 
        return TRUE; 
} 
/////////////////the property of the image//////////////// 
/////////Mean grey value 
BYTE	CImage::MeanGrey() 
{ 
        BYTE	avegrey; 
        double sum = 0.0; 
        DWORD i, imgsize; 
        imgsize = (DWORD) Width() * Height(); 
        BYTE*	pData = Data(); 
        for(i=0;i<imgsize;i++) 
                sum += pData[i]; 
        avegrey = (BYTE)(sum / imgsize); 
        Dib(); 
        return avegrey; 
} 
 
 
double	CImage::CleanMeasure() 
{ 
        double	diff	=	0.0; 
        DWORD	i; 
        BYTE	mean	=	MeanGrey(); 
        BYTE*	pData	=	Data(); 
        DWORD	imgSize	=	Width() * Height(); 
        for(i=0,diff=0.0; i<imgSize; i++) 
                diff += (pData[i] - mean) * (pData[i] - mean); 
        diff = sqrt(diff) / imgSize; 
        Dib(); 
        return diff; 
} 
 
BYTE	CImage::Get8NeiborAver(BYTE* pGreyData, WORD w, WORD h, CPoint pos) 
{ 
        double temp; 
        int x = pos.x; 
        int y = pos.y; 
        int t = y * w + x; 
        if(x == 0 && y != 0) 
        { 
                temp  =	pGreyData[t-w] + pGreyData[t-w+1] + 
                        pGreyData[t+1] +  
                        pGreyData[t+w] + pGreyData[t+w+1]; 
                temp /= 5; 
                return (BYTE)temp; 
        } 
        if(x != 0 && y == 0) 
        { 
                temp  =	pGreyData[t-1] + pGreyData[t+1] +  
                        pGreyData[t+w-1] + pGreyData[t+w] + pGreyData[t+w+1]; 
                temp /= 5; 
                return (BYTE)temp; 
        } 
        if(x == 0 && y != 0) 
        { 
                temp  =	pGreyData[t+1] + 
                        pGreyData[t+w] + pGreyData[t+w+1]; 
                temp /= 3; 
                return (BYTE)temp; 
        } 
 
        if(x == w-1 && y != h-1) 
        { 
                temp  =	pGreyData[t-w-1] + pGreyData[t-w] + 
                        pGreyData[t-1] +  
                        pGreyData[t+w-1] + pGreyData[t+w]; 
                temp /= 5; 
                return (BYTE)temp; 
        } 
        if(x != w-1 && y == h-1) 
        { 
                temp  =	pGreyData[t-w-1] + pGreyData[t-w] + pGreyData[t-w+1] + 
                        pGreyData[t-1] + pGreyData[t+1]; 
                temp /= 5; 
                return (BYTE)temp; 
        } 
        if(x = w-1 && y == h-1) 
        { 
                temp  =	pGreyData[t-w-1] + pGreyData[t-w] +  
                        pGreyData[t-1]; 
                temp /= 3; 
                return (BYTE)temp; 
        } 
        temp  =	pGreyData[t-w-1] + pGreyData[t-w] + pGreyData[t-w+1] + 
                pGreyData[t-1]   + pGreyData[t+1] + 
                pGreyData[t+w-1] + pGreyData[t+w] + pGreyData[t+w+1]; 
        temp /= 8; 
        return (BYTE)temp; 
} 
 
 
/////////////////////////////////////////////// 
/* 
* SSG, 1999.6. 2 
* Save the data as text 
*/ 
/////////////////////////////////////////////// 
BOOL CImage::SaveAsText(CString	 filename, BOOL	bIsBinary) 
{ 
        int		w; 
        long	l, size; 
        char	buf[20]; 
        CFile	f; 
        BYTE	*pData; 
 
        pData = Data(); 
 
        if (m_pDib == NULL) 
                return FALSE; 
        if(Bits() != 8) { 
                AfxMessageBox("It is not 8-greylevel image!");		 
                return false;	 
        } 
        w = Width(); 
        size = w * Height(); 
 
        f.Open(filename, CFile::modeCreate | CFile::modeWrite ); 
        if(bIsBinary) 
        { 
                for(l=0; l<size; l++) 
                { 
                        if(*(pData + l) != 0) 
                                sprintf(buf, "*"); 
                        else 
                                sprintf(buf, "."); 
                        f.Write(buf, strlen(buf)); 
                        if( (l+1)%w == 0){ 
                                f.Write("\n", 1); 
                        } 
                } 
        } 
        else 
        { 
                for(l=0; l<size; l++) 
                { 
                        sprintf(buf, "%3d ", *(pData + l) ); 
                        f.Write(buf, strlen(buf)); 
                        if( (l+1)%w == 0){ 
                                f.Write("\n", 1); 
                        } 
                } 
        } 
        f.Close(); 
 
        Dib(); 
        return TRUE; 
} 
 
BOOL CImage::ValidImage() 
{ 
        if(m_dwLength == 0L || m_pData == NULL || m_pDib == NULL) 
                return FALSE; 
        else 
                return TRUE; 
} 
 
/******************************************************************** 
///////////////////////////from the CImage/////////////////// 
********************************************************************/ 
 
 
 
BOOL CImage::Convert2I_Image() 
{ 
        if(Bits() != 24) 
                return FALSE; 
 
        int		w = Width(); 
        int		h = Height(); 
 
        CImage	*pI_Img = new CImage(CSize(w, h), 256, 8); 
 
        BYTE		*pI_Data = pI_Img->Data(); 
        BYTE		*pColorData = Data(); 
 
        long		size, l; 
        double		I, Q; 
        BYTE		R, G, B, Y; 
        size = long(Width() * Height()); 
        for(l=0; l<size; l++) 
        { 
                B = *pColorData++; 
                G = *pColorData++; 
                R = *pColorData++; 
                RGB2YIQ(R, G, B, Y, I, Q); 
                *pI_Data++ = BYTE( I ); 
        } 
 
        pI_Data = pI_Img->Dib(); 
        *this = *pI_Img; 
        delete pI_Img; 
 
        return TRUE; 
} 
 
BOOL CImage::GetRImage(CImage * pRImg) 
{ 
        if(Bits() != 24) 
                return FALSE; 
 
        int		w = Width(); 
        int		h = Height(); 
 
        BYTE		*pRData = pRImg->Data(); 
        BYTE		*pColorData = Data(); 
 
        long		size, l; 
        size = long(Width() * Height() * 3); 
 
        for(l=0; l<size; l+=3) 
                *pRData++ = *(pColorData+l+2); 
 
        Dib(); 
        pRImg->Dib(); 
 
        return TRUE; 
} 
 
BOOL CImage::GetGImage(CImage * pGImg) 
{ 
        if(Bits() != 24) 
                return FALSE; 
 
        int		w = Width(); 
        int		h = Height(); 
 
        BYTE		*pGData = pGImg->Data(); 
        BYTE		*pColorData = Data(); 
 
        long		size, l; 
        size = long(Width() * Height() * 3); 
 
        for(l=0; l<size; l+=3) 
                *pGData++ = *(pColorData+l+1); 
 
        Dib(); 
        pGImg->Dib(); 
 
        return TRUE; 
} 
 
BOOL CImage::GetBImage(CImage * pBImg) 
{ 
        if(Bits() != 24) 
                return FALSE; 
 
        int		w = Width(); 
        int		h = Height(); 
 
        BYTE		*pBData = pBImg->Data(); 
        BYTE		*pColorData = Data(); 
 
        long		size, l; 
        size = long(Width() * Height() * 3); 
 
        for(l=0; l<size; l+=3) 
                *pBData++ = *(pColorData+l); 
 
        Dib(); 
        pBImg->Dib(); 
 
        return TRUE; 
} 
 
/* 
* return paras: 
* pfr:  f(u,v) ʵ 
* pfi:  f(u,v) 鲿 
* pfm:  ģ 
* pfa:   
*/ 
 
 
BOOL CImage::CenterRotateInImagePlane(double angle, BOOL bClockWise) 
{ 
        double	radianAngle; 
        double	oldx, oldy; 
        double  cofX, cofY, FTmp; 
        double  SinCita, CosCita; 
        int		i, j, x1; 
        long	w, h, ImageSize; 
 
        w = Width(); 
        h = Height(); 
        ImageSize = (long)w*h; 
 
        CPoint fixpos = CPoint(w/2, h/2); 
        if(bClockWise) 
                radianAngle = angle*3.1415926/180.0; 
        else 
                radianAngle = -angle*3.1415926/180.0; 
        SinCita = sin(radianAngle); 
        CosCita = cos(radianAngle); 
 
        CImage* pTempImg = new CImage; 
        *pTempImg = *this; 
 
        BYTE* pOriData = Data(); 
        BYTE* pNewData = pTempImg->Data(); 
 
        double t1, t2; 
        long t3 = 0; 
        for(j=0; j<h; j++) 
        { 
                t1 = SinCita * (j - fixpos.y); 
                t2 = CosCita * (j - fixpos.y); 
                t3 = j * w; 
                for(i=0; i<w; i++) 
                { 
                        oldx = fixpos.x +  (CosCita * (i - fixpos.x) + t1); 
                        oldy = fixpos.y +  (t2 - SinCita * (i - fixpos.x)); 
                        if(oldx < w-1 && oldy < h-1 && oldx >= 0 && oldy >= 0) 
                        {	 
                                cofX = oldx - int(oldx); 
                                cofY = oldy - int(oldy); 
                                x1 = ((int)oldy) * w + (int)oldx; 
                                FTmp = (1-cofX) * (double)pOriData[x1] + cofX * (double)pOriData[x1 + 1]; 
                                FTmp = (1-cofY) * FTmp + cofY * ((1-cofX) * (double)pOriData[x1 + w] + cofX * (double)pOriData[x1 + w + 1]); 
                                pNewData[j * w + i] = int (FTmp + 0.5); 
                        } 
                        else  
                                pNewData[j * w + i] = 0; 
                } 
        } 
 
        pTempImg->Dib(); 
        *this = *pTempImg; 
        Dib(); 
        delete pTempImg; 
        return true; 
 
} 
 
 
DWORD CImage::ByteNumForOneLine(WORD nDIBWidth, int nBpp) 
{ 
        DWORD dwBytes = (nDIBWidth * nBpp) / 32; 
        if ((nDIBWidth * nBpp) % 32)  
                dwBytes ++; 
 
        dwBytes *= 4;//bytes per line 
 
        return	dwBytes; 
}