// BMP.cpp: implementation of the BMP class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Image Processing.h"
#include "BMP.h"
#include "stdio.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
BMP::BMP()
{
}
BMP::~BMP()
{
}
BOOL BMP::Test()
{
lpSrcFile = "c:\\temp\\1.bmp";
lpDstFile = "c:\\temp\\2.bmp";
bmDegree = 180;
Read();
bmDstWidth = bmWidth;
bmDstHeight = bmHeight;
hDst = GlobalAlloc(GPTR, (INT)((bmDstWidth + 15) / 16) * 2 * bmDstHeight);
bmDstBits = (LPBYTE)GlobalLock(hDst);
Rotate();
Write();
if (hDst)
GlobalUnlock(hDst);
if (bmDstBits)
GlobalFree(bmDstBits);
return TRUE;
}
BOOL BMP::Read()
{
BITMAPFILEHEADER fileHead;
BITMAPINFOHEADER infoHead;
DWORD size;
HANDLE hRead;
if (!(hRead = CreateFile(lpSrcFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)))
{
MessageBox(NULL, "Open file failed", "Error", MB_OK);
return FALSE;
}
ReadFile(hRead, &fileHead, sizeof(BITMAPFILEHEADER), &size, NULL);
if (fileHead.bfType != 0x4D42)
{
MessageBox(NULL, "Not BMP file", "Error", MB_OK);
CloseHandle(hRead);
return FALSE;
}
hSrc = GlobalAlloc(GPTR, (fileHead.bfSize - fileHead.bfOffBits));
bmSrcBits = (LPBYTE)GlobalLock(hSrc);
ReadFile(hRead, &infoHead, sizeof(BITMAPINFOHEADER), &size, NULL);
bmWidth = infoHead.biWidth;
bmWidthBytes = (INT)((bmWidth + 15) / 16) * 2;
bmHeight = infoHead.biHeight;
bmPlanes = infoHead.biPlanes;
bmBitsPixel = infoHead.biBitCount;
bmXReso = infoHead.biXPelsPerMeter;
bmYReso = infoHead.biYPelsPerMeter;
switch(infoHead.biBitCount)
{
case 1:
size = 2;
break;
case 4:
size = 16;
break;
case 8:
size = 256;
break;
default:
size = 0;
break;
}
if (size > 0)
{
hPal = GlobalAlloc(GPTR, size * sizeof(DWORD));
bmPallete = (LPDWORD)GlobalLock(hPal);
ReadFile(hRead, bmPallete, size * sizeof(DWORD), &size, NULL);
}
SetFilePointer(hRead, fileHead.bfOffBits, NULL, FILE_BEGIN);
ReadFile(hRead, bmSrcBits, (fileHead.bfSize - fileHead.bfOffBits), &size, NULL);
CloseHandle(hRead);
return TRUE;
}
BOOL BMP::Write()
{
BITMAPFILEHEADER fileHead;
BITMAPINFOHEADER infoHead;
DWORD size, palSize;
HANDLE hWrite;
memset(&fileHead, 0, sizeof(BITMAPFILEHEADER));
memset(&infoHead, 0, sizeof(BITMAPINFOHEADER));
if (!(hWrite = CreateFile(lpDstFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL)))
{
MessageBox(NULL, "Open file failed", "Error", MB_OK);
return FALSE;
}
infoHead.biSize = sizeof(BITMAPINFOHEADER);
infoHead.biWidth = bmDstWidth;
infoHead.biHeight = bmDstHeight;
infoHead.biPlanes = bmPlanes;
infoHead.biBitCount = bmBitsPixel;
infoHead.biClrImportant = 2;
infoHead.biXPelsPerMeter = bmXReso;
infoHead.biYPelsPerMeter = bmYReso;
infoHead.biSizeImage = ((INT)((infoHead.biWidth * infoHead.biBitCount + 15) / 16) * 2 * infoHead.biHeight);
fileHead.bfType = 0x4D42; //'BM'
switch (infoHead.biBitCount)
{
case 1:
palSize = 2;
break;
case 4:
palSize = 16;
break;
case 8:
palSize = 256;
break;
default:
palSize = 0;
break;
}
fileHead.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER) + palSize * sizeof(DWORD);
fileHead.bfSize = fileHead.bfOffBits; //head size
fileHead.bfSize += infoHead.biSizeImage; //data size
WriteFile(hWrite, &fileHead, sizeof(BITMAPFILEHEADER), &size, NULL);
WriteFile(hWrite, &infoHead, sizeof(BITMAPINFOHEADER), &size, NULL);
WriteFile(hWrite, bmPallete, palSize * sizeof(DWORD), &size, NULL);
WriteFile(hWrite, bmDstBits, (fileHead.bfSize - fileHead.bfOffBits), &size, NULL);
CloseHandle(hWrite);
if (hPal)
GlobalUnlock(hPal);
if (bmPallete)
GlobalFree(bmPallete);
if (hSrc)
GlobalUnlock(hSrc);
if (bmSrcBits)
GlobalFree(bmSrcBits);
return TRUE;
}
bool BMP::Rotate()
{
int i, j, k;
int pos1, pos2;
switch (bmDegree)
{
case 180:
switch (bmBitsPixel)
{
case 1:
for (j = 0; j < bmHeight; j++)
{
if (bmWidthBytes == (bmWidth / 8))
{
for (i = 0; i < bmWidthBytes; i++)
{
pos1 = (j * bmWidthBytes + i);
pos2 = (bmHeight - j - 1) * bmWidthBytes + bmWidth / 8 - 1 - i;
*(bmDstBits + pos1) = shift[*(bmSrcBits + pos2)];
}
}
else
{
for (i = 0; i < bmWidth; i++)
{
pos1 = (j * bmWidthBytes + i / 8);
pos2 = (j * bmWidthBytes + (bmWidth - 1 - i) / 8);
}
}
}
break;
case 4:
break;
case 8:
case 16:
case 24:
case 32:
for (j = 0; j < bmHeight; j++)
{
for (i = 0; i < bmWidth; i++)
{
pos1 = j * bmWidthBytes + i * bmBitsPixel / 8;
pos2 = (bmHeight - j - 1) * bmWidthBytes + (bmWidth - i - 1) * bmBitsPixel / 8;
for (k = 0; k < bmBitsPixel / 8; k++)
{
*(bmDstBits + pos1 + k) = *(bmSrcBits + pos2 + k);
}
}
}
break;
default:
memcpy(bmDstBits, bmSrcBits, bmHeight * bmWidthBytes);
break;
}
break;
case 90:
switch (bmBitsPixel)
{
case 1:
break;
case 4:
break;
case 8:
case 16:
case 24:
case 32:
LONG bmDstWidth, bmDstWidthBytes, bmDstHeight;
int pos1, pos2;
bmDstHeight = bmWidth;
bmDstWidth = bmHeight;
bmDstWidthBytes = (int)((bmDstWidth * bmBitsPixel + 15) / 16) * 2;
for (j = 0; j < bmDstHeight; j++)
{
for (i = 0; i < bmDstWidth; i++)
{
pos1 = j * bmDstWidthBytes + i * bmBitsPixel / 8;
pos2 = i * bmWidthBytes + (bmWidth - j - 1) * bmBitsPixel / 8;
for (k = 0; k < bmBitsPixel / 8; k++)
{
*(bmDstBits + pos1 + k) = *(bmSrcBits + pos2 + k);
}
}
}
break;
default:
memcpy(bmDstBits, bmSrcBits, bmHeight * bmWidthBytes);
break;
}
break;
case 270:
switch (bmBitsPixel)
{
case 1:
break;
case 4:
break;
case 8:
case 16:
case 24:
case 32:
LONG bmDstWidth, bmDstWidthBytes, bmDstHeight;
int pos1, pos2;
bmDstHeight = bmWidth;
bmDstWidth = bmHeight;
bmDstWidthBytes = (int)((bmDstWidth * bmBitsPixel + 15) / 16) * 2;
for (j = 0; j < bmDstHeight; j++)
{
for (i = 0; i < bmDstWidth; i++)
{
pos1 = j * bmDstWidthBytes + i * bmBitsPixel / 8;
pos2 = (bmHeight - i - 1) * bmWidthBytes + j * bmBitsPixel / 8;
for (k = 0; k < bmBitsPixel / 8; k++)
{
*(bmDstBits + pos1 + k) = *(bmSrcBits + pos2 + k);
}
}
}
break;
default:
break;
}
break;
case 0:
memcpy(bmDstBits, bmSrcBits, bmHeight * bmWidthBytes);
break;
default:
memcpy(bmDstBits, bmSrcBits, bmHeight * bmWidthBytes);
break;
}
return TRUE;
}