📄 image.cpp
字号:
for(j=0; j<lBpl; j++)
{
temp = p1[j];
p1[j] = p2[j];
p2[j] = temp;
}
p1 += lBpl;
}
//To pend the width of the image for windows display.
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);
long 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(30), 30);
}
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 != 3)
{
if(sfilehead.GetAt(dwDataPos) == '\n')
tt++;
dwDataPos++;
if(dwDataPos > 30)
{
AfxMessageBox("The format is wrong!");
return false;
}
}
dwFileLength -= dwDataPos;
i=0; 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)
{
BOOL bReturn;
CString FileName=pFile->GetFilePath();
m_strFileName = FileName;
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(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);
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::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")
return WriteAsData(pFile);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -