Please include comments Can you create a c++ program program that loads the orig
ID: 3747903 • Letter: P
Question
Please include comments
Can you create a c++ program program that loads the original 8-bit bitmap grasyscale file and an 8-bit image grayscale overlay file which must have same size using this algorithm:
if a pixel is black in the overlay image, the corresponding pixel in out1 is white. If a pixel is not black in the overlay image, the corresponding pixel in out1 equals the corresponding pixel in the original image. We will call this way of processing image overlay (IO).
Images of any size up to 1024x768 pixels
Explanation / Answer
#include "bmpclass.h"
BitMapClass::BitMapClass(char *fileName)
{
clrPalette = NULL;
fin.open(fileName, ios::in | ios::binary);
GetFileHeader();
GetImgInfo();
GetRGBPalette();
GetPixelData();
}
void BitMapClass::GetFileHeader()
{
if (!fin.is_open()) throw string("File Read Error");
else
{
fin.read((char*)&fileHeader.bfType, sizeof(fileHeader.bfType));
if (fileHeader.bfType != 19778) throw string("Invalid Filetype");
else
{
fin.read((char*)&fileHeader.bfSize, sizeof(fileHeader.bfSize));
fin.read((char*)&fileHeader.bfRes1, sizeof(fileHeader.bfRes1));
fin.read((char*)&fileHeader.bfRes2, sizeof(fileHeader.bfRes2));
fin.read((char*)&fileHeader.bfOffBits, sizeof(fileHeader.bfOffBits));
}
}
}
void BitMapClass::GetImgInfo()
{
if (!fin.is_open()) throw string("File Read Error");
else
{
fin.read((char*)&imgInfo.biSize, sizeof(imgInfo.biSize));
fin.read((char*)&imgInfo.biWidth, sizeof(imgInfo.biWidth));
fin.read((char*)&imgInfo.biHeight, sizeof(imgInfo.biHeight));
fin.read((char*)&imgInfo.biPlanes, sizeof(imgInfo.biPlanes));
fin.read((char*)&imgInfo.biBitCount, sizeof(imgInfo.biBitCount));
fin.read((char*)&imgInfo.biCompression, sizeof(imgInfo.biCompression));
fin.read((char*)&imgInfo.biSizeImage, sizeof(imgInfo.biSizeImage));
fin.read((char*)&imgInfo.biXPelsPerMeter, sizeof(imgInfo.biXPelsPerMeter));
fin.read((char*)&imgInfo.biYPelsPerMeter, sizeof(imgInfo.biYPelsPerMeter));
fin.read((char*)&imgInfo.biClrUsed, sizeof(imgInfo.biClrUsed));
fin.read((char*)&imgInfo.biClrImportant, sizeof(imgInfo.biClrImportant));
}
}
void BitMapClass::GetPixelData()
{
int size = fileHeader.bfSize - fileHeader.bfOffBits;
char *tempPixelData = new char[size];
for (int i=0; i < size; i++)
fin.read((char*)&tempPixelData[i], 1);
unsigned long byteWidth, padWidth;
byteWidth = padWidth = (unsigned long)((float)imgInfo.biWidth*(float)imgInfo.biBitCount/8.0);
while (padWidth % 4 != 0)
padWidth++;
dword diff;
int offset;
long height;
height = imgInfo.biHeight;
diff = height * byteWidth;
pixelData = new char[diff];
if (height > 0)
{
int j = imgInfo.biSize - 3;
offset = padWidth - byteWidth;
for (int i=0; i < imgInfo.biSize; i += 3)
{
if ((i + 1) % padWidth == 0)
i += offset;
*(pixelData + j + 2) = *(tempPixelData + i);
*(pixelData + j + 1) = *(tempPixelData + i + 1);
*(pixelData + j) = *(tempPixelData + i + 2);
j++;
}
}
for (int i=0; i < size; i++)
pixelData[i] = tempPixelData[i];
fin.close();
}
void BitMapClass::GetRGBPalette()
{
if (!fin.is_open()) throw string("File Read Error");
else
{
int numColors=1 << imgInfo.biBitCount;
clrPalette = new RGBPalette[numColors];
if (imgInfo.biBitCount < 24)
{
for (int i=0; i < numColors; i++)
{
fin.read(&clrPalette[i].rgbBlue, 1);
fin.read(&clrPalette[i].rgbGreen, 1);
fin.read(&clrPalette[i].rgbRed, 1);
fin.read(&clrPalette[i].rgbReserved, 1);
}
}
}
}
//
void BitMapClass::SendGrayScale(ofstream& fout)
{
/* This is the method I'm having trouble with */
word *biBitCount = new word(8);
int numColors=1 << *biBitCount;
dword *bfSize = new dword(54 + (4 * numColors) + (imgInfo.biWidth * imgInfo.biHeight));
dword *size = new dword(*bfSize - fileHeader.bfOffBits);
char *gPixelData = new char[(*size)];
int j = 0;
for (int i=0; i < (fileHeader.bfSize - fileHeader.bfOffBits); i+=3)
{
gPixelData[j] = (float)(((pixelData[i])*0.299)
+ ((pixelData[i+1])*0.587)
+ ((pixelData[i+2])*0.114));
j++;
}
if (fout.is_open())
{
fout.write((char*)&fileHeader.bfType, sizeof(fileHeader.bfType));
fout.write((char*)&bfSize, sizeof(dword));
fout.write((char*)&fileHeader.bfRes1, sizeof(fileHeader.bfRes1));
fout.write((char*)&fileHeader.bfRes2, sizeof(fileHeader.bfRes2));
fout.write((char*)&fileHeader.bfOffBits, sizeof(fileHeader.bfOffBits));
fout.write((char*)&size, sizeof(dword));
fout.write((char*)&imgInfo.biWidth, sizeof(imgInfo.biWidth));
fout.write((char*)&imgInfo.biHeight, sizeof(imgInfo.biHeight));
fout.write((char*)&imgInfo.biPlanes, sizeof(imgInfo.biPlanes));
fout.write((char*)&biBitCount, sizeof(imgInfo.biBitCount));
fout.write((char*)&imgInfo.biCompression, sizeof(imgInfo.biCompression));
fout.write((char*)&imgInfo.biSizeImage, sizeof(imgInfo.biSizeImage));
fout.write((char*)&imgInfo.biXPelsPerMeter, sizeof(imgInfo.biXPelsPerMeter));
fout.write((char*)&imgInfo.biYPelsPerMeter, sizeof(imgInfo.biYPelsPerMeter));
fout.write((char*)&imgInfo.biClrUsed, sizeof(imgInfo.biClrUsed));
fout.write((char*)&imgInfo.biClrImportant, sizeof(imgInfo.biClrImportant));
ifstream clrIn;
clrIn.open("gs.dat", ios::in | ios::binary);
if (clrPalette)
delete clrPalette;
clrPalette = new RGBPalette[numColors];
for (int i=0; i < numColors; i++)
{
clrIn.read(&clrPalette[i].rgbBlue, 1);
clrIn.read(&clrPalette[i].rgbGreen, 1);
clrIn.read(&clrPalette[i].rgbRed, 1);
clrIn.read(&clrPalette[i].rgbReserved, 1);
fout.write(&clrPalette[i].rgbBlue, 1);
fout.write(&clrPalette[i].rgbGreen, 1);
fout.write(&clrPalette[i].rgbRed, 1);
fout.write(&clrPalette[i].rgbReserved, 1);
}
for (int i=0; i < (*size); i++)
{
fout.write(&gPixelData[i], 1);
}
}
}
//
void BitMapClass::SendToFile(ofstream& fout)
{
dword size = fileHeader.bfSize - fileHeader.bfOffBits;
int numColors=1 << imgInfo.biBitCount;
if (fout.is_open())
{
fout.write((char*)&fileHeader.bfType, sizeof(fileHeader.bfType));
fout.write((char*)&fileHeader.bfSize, sizeof(fileHeader.bfSize));
fout.write((char*)&fileHeader.bfRes1, sizeof(fileHeader.bfRes1));
fout.write((char*)&fileHeader.bfRes2, sizeof(fileHeader.bfRes2));
fout.write((char*)&fileHeader.bfOffBits, sizeof(fileHeader.bfOffBits));
fout.write((char*)&imgInfo.biSize, sizeof(imgInfo.biSize));
fout.write((char*)&imgInfo.biWidth, sizeof(imgInfo.biWidth));
fout.write((char*)&imgInfo.biHeight, sizeof(imgInfo.biHeight));
fout.write((char*)&imgInfo.biPlanes, sizeof(imgInfo.biPlanes));
fout.write((char*)&imgInfo.biBitCount, sizeof(imgInfo.biBitCount));
fout.write((char*)&imgInfo.biCompression, sizeof(imgInfo.biCompression));
fout.write((char*)&imgInfo.biSizeImage, sizeof(imgInfo.biSizeImage));
fout.write((char*)&imgInfo.biXPelsPerMeter, sizeof(imgInfo.biXPelsPerMeter));
fout.write((char*)&imgInfo.biYPelsPerMeter, sizeof(imgInfo.biYPelsPerMeter));
fout.write((char*)&imgInfo.biClrUsed, sizeof(imgInfo.biClrUsed));
fout.write((char*)&imgInfo.biClrImportant, sizeof(imgInfo.biClrImportant));
if (imgInfo.biBitCount < 24)
{
for (int i=0; i < numColors; i++)
{
fout.write(&clrPalette[i].rgbBlue, 1);
fout.write(&clrPalette[i].rgbGreen, 1);
fout.write(&clrPalette[i].rgbRed, 1);
fout.write(&clrPalette[i].rgbReserved, 1);
}
}
for (int i=0; i < size; i++)
{
fout.write(&pixelData[i], 1);
}
}
}
void BitMapClass::TextDumpFileHeader(ostream& out)
{
if (!out) throw string("Invalid Output Stream");
else
{
cout << fileHeader.bfType << endl;
cout << fileHeader.bfSize << endl;
cout << fileHeader.bfRes1 << endl;
cout << fileHeader.bfRes2 << endl;
cout << fileHeader.bfOffBits << endl;
}
}
void BitMapClass::TextDumpImgInfo(ostream& out)
{
if (!out) throw string("Invalid Output Stream");
else
{
cout << imgInfo.biSize << endl;
cout << imgInfo.biWidth << endl;
cout << imgInfo.biHeight << endl;
cout << imgInfo.biPlanes << endl;
cout << imgInfo.biBitCount << endl;
cout << imgInfo.biCompression << endl;
cout << imgInfo.biSizeImage << endl;
cout << imgInfo.biXPelsPerMeter << endl;
cout << imgInfo.biYPelsPerMeter << endl;
cout << imgInfo.biClrUsed << endl;
cout << imgInfo.biClrImportant << endl;
}
}
void BitMapClass::TextDumpClrPalette(ostream& out)
{
int numColors=1 << imgInfo.biBitCount;
for (int i=0; i < numColors; i++)
{
cout << (int)clrPalette[i].rgbBlue << ' ';
cout << (int)clrPalette[i].rgbGreen << ' ';
cout << (int)clrPalette[i].rgbRed << ' ';
cout << (int)clrPalette[i].rgbReserved << endl;
}
}
BitMapClass::~BitMapClass()
{
}
8-bit bitmap grayscale
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/*-------STRUCTURES---------*/
typedef struct {int rows; int cols; int bits; unsigned char* data;} sImage;
/*-------PROTOTYPES---------*/
long getImageInfo(FILE*, long, int);
void copyImageInfo(FILE*, FILE*);
void copyColorTable(FILE*, FILE*, int);
int main()
{
FILE *bmpInput, *bmpOutput;
sImage originalImage;
unsigned char someChar;
unsigned char* pChar;
int nColors; /* BMP number of colors */
long fileSize; /* BMP file size */
int vectorSize; /* BMP vector size */
int r, c; /* r = rows, c = cols */
int pixels[600][600];
char imagein[30];
char imageout[30];
/* initialize pointer */
someChar = '0';
pChar = &someChar;
printf("Enter input image : ");
gets(imagein);
printf("Enter output image : ");
gets(imageout);
/*--------READ INPUT FILE------------*/
bmpInput = fopen(imagein, "rb");
fseek(bmpInput, 0L, SEEK_END);
/*--------DECLARE OUTPUT FILE--------*/
bmpOutput = fopen(imageout, "wb");
/*--------GET BMP DATA---------------*/
originalImage.cols = (int)getImageInfo(bmpInput, 18, 4);
originalImage.rows = (int)getImageInfo(bmpInput, 22, 4);
originalImage.bits = (int)getImageInfo(bmpInput, 28, 4);
fileSize = getImageInfo(bmpInput, 2, 4);
nColors = getImageInfo(bmpInput, 46, 4);
vectorSize = fileSize - (14 + 40 + 4*nColors);
/*-------PRINT DATA TO SCREEN-------------*/
printf("Width: %d ", originalImage.cols);
printf("Height: %d ", originalImage.rows);
printf("Bits per Pixel: %d ", originalImage.bits);
printf("File size: %ld ", fileSize);
printf("# Colors: %d ", nColors);
printf("Vector size: %d ", vectorSize);
copyImageInfo(bmpInput, bmpOutput);
copyColorTable(bmpInput, bmpOutput, nColors);
/*----START AT BEGINNING OF RASTER DATA-----*/
fseek(bmpInput, (54 + 4*nColors), SEEK_SET);
/*----------READ RASTER DATA----------*/
for(r=0; r<=originalImage.rows - 1; r++)
{
for(c=0; c<=originalImage.cols - 1; c++)
{
/*-----read data, reflect and write to output file----*/
fread(pChar, sizeof(char), 1, bmpInput);
pixels[r][c] = *pChar;
*pChar = 255 - *pChar;
fwrite(pChar, sizeof(char), 1, bmpOutput);
}
}
fclose(bmpInput);
fclose(bmpOutput);
getch();
}
/*----------GET IMAGE INFO SUBPROGRAM--------------*/
long getImageInfo(FILE* inputFile, long offset, int numberOfChars)
{
unsigned char *ptrC;
long value = 0L;
unsigned char dummy;
int i;
dummy = '0';
ptrC = &dummy;
fseek(inputFile, offset, SEEK_SET);
for(i=1; i<=numberOfChars; i++)
{
fread(ptrC, sizeof(char), 1, inputFile);
/* calculate value based on adding bytes */
value = (long)(value + (*ptrC)*(pow(256, (i-1))));
}
return(value);
} /* end of getImageInfo */
/*-------------COPIES HEADER AND INFO HEADER----------------*/
void copyImageInfo(FILE* inputFile, FILE* outputFile)
{
unsigned char *ptrC;
unsigned char dummy;
int i;
dummy = '0';
ptrC = &dummy;
fseek(inputFile, 0L, SEEK_SET);
fseek(outputFile, 0L, SEEK_SET);
for(i=0; i<=50; i++)
{
fread(ptrC, sizeof(char), 1, inputFile);
fwrite(ptrC, sizeof(char), 1, outputFile);
}
}
/*----------------COPIES COLOR TABLE-----------------------------*/
void copyColorTable(FILE* inputFile, FILE* outputFile, int nColors)
{
unsigned char *ptrC;
unsigned char dummy;
int i;
dummy = '0';
ptrC = &dummy;
fseek(inputFile, 54L, SEEK_SET);
fseek(outputFile, 54L, SEEK_SET);
for(i=0; i<=(4*nColors); i++) /* there are (4*nColors) bytesin color table */
{
fread(ptrC, sizeof(char), 1, inputFile);
fwrite(ptrC, sizeof(char), 1, outputFile);
}
}