////////////////////////////////////////////////////////////////////////////////
// //
// Class Name : CImage //
// //
// Function : Operating the image. //
// //
// Developer : (C) Intel & Shiguang SHAN & Liangguo ZHANG , ...-2002-2003 //
// ,Vilab of Harbin Institute of Technology //
// //
// Dev. Records : //
// //
////////////////////////////////////////////////////////////////////////////////
//
//image.cpp: Implementation of the CImage Class.
#include "stdafx.h"
#include "math.h"
#include "global.h"
#include "resource.h"
#include "image.h"
#include <windowsx.h> // for GlobalAllocPtr
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
{
//NOTE: The type(DIB/non-DIB) of Image-constructed equals to original-Image.
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();
}
//#######################################################################################
CImage::CImage(CImage& img, CPoint start, CSize size)
{
int bpp;
int bytepp;
long hdlen;//size of the DIB HeaderInfo and Palette
LPBITMAPINFOHEADER pBMIH;
ASSERT(img.m_pDib);
WORD dww = img.Width();
WORD dwh = img.Height();
if(((size.cx+start.x) > dww) || ((size.cy+start.y) > dwh))
{
AfxMessageBox("Image size is too large!");
return;
}
img.Data(); //form non-DIB type image.
m_bIsDIB = FALSE;
hdlen = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * img.NumColors();
bpp = img.Bits();
bytepp = bpp / 8;
ASSERT(bpp != 16 && bpp != 32);
DWORD bypeinoneline = ByteNumForOneLine((WORD)size.cx, bpp);//Bytes per line
m_dwLength = hdlen + bypeinoneline * size.cy;
if(!AllocateMemory())
{
return;
}
memcpy(m_pDib, img.m_pDib, hdlen); // m_pDib-->point to BITMAPINFOHEADER structure
pBMIH = BMInfoHdPtr();
pBMIH->biWidth = size.cx;
pBMIH->biHeight = size.cy;
pBMIH->biSizeImage = size.cx * size.cy * bytepp;
m_pData = (BYTE*)(m_pDib + hdlen); // m_pData-->point to Actual-DIB-Img-Data
BYTE* p1, *p2;
long t1, t2;
t1 = dww * bytepp;
t2 = size.cx * bytepp;
p1 = (BYTE*)(img.m_pData + (start.y * dww + start.x) * bytepp);
p2 = m_pData;
for(int i=0; i<(int)size.cy; i++)
{
memcpy(p2, p1, t2);
p1 += t1;
p2 += t2;
}
Dib(); //form DIB type image.
img.Dib(); //form DIB type image again.
m_pPal = new CPalette;
CreateDIBPalette();
}
//#######################################################################################
//NOTE: used to create a DIB of size 'size' without 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); // m_pData-->point to Actual-DIB-Img-Data
SetDIB();
m_pPal = new CPalette;
CreateGreyPalette();
}
//#######################################################################################
CImage& CImage::operator=(const CImage& img)
{
//NOTE: part copy constructor
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;
}
//#######################################################################################
//NOTE: constructs a DIB from the contents of a bitmap
// 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)
CImage::CImage(CDC* pDC, int nBt, BOOL bCompr):m_bIsDIB(TRUE)
{
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 =