C++ Newbie needs a c++ expert converting bits to bytes
I need some C++ experts to help me with a problem I have in converting a PBM file to a PGM file. These files are used to store digital images. The PBM file uses monochrome to display images while the PGM file is a grayscale image. I have written a test program that works somewhat. The problem I have is that the PBM format uses 1 bit to represent a pixel while the PGM format uses 1 byte to represent a pixel. Therefore 1 byte in PBM format represents 8 pixels. I need help in converting those bits to bytes for the PGM format. I am not sure how to achieve this. I have never really had any experience in masking bytes. Here is my code thus far:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
/*** New Data Types ***/
typedef unsigned char BYTE;
// create data structure to hold image
struct PIC
{
unsigned int nChannel;
bool InterLeaved;
unsigned int Width, Height;
BYTE *img;
};
//function that accepts an outstream file and a PIC object to
//and writes the output stream to the PIC object
void WritePGM(ofstream & outfile, PIC pic)
{
outfile << "P5" << endl;
outfile << pic.Width << " " << pic.Height << endl;
outfile << 255 << endl;
outfile.write(reinterpret_cast<char *>(pic.img), pic.Width*pic.Height);
}
//function that accepts an infile object and a PIC Object
//and reads in the PIC object
void LoadImage(ifstream &infile, PIC &pic)
{
infile.read(reinterpret_cast<char *>(pic.img), pic.Width*pic.Height);
}
//function that loads in the header
bool LoadP4Header(ifstream &infile, PIC &pic)
{
bool rtv = true;;
char buf[16];
int bufIndex;
int width, height, maxValue;
infile.read(buf, 2); // get the magic number
buf[2]='\0';
if(buf[0] == 'P' && buf[1] == '4'){
infile.read(buf, 1);
while(isspace(buf[0])){ // Skip white space(s)
infile.read(buf,1);
}
if(buf[0] == '#') { // Skip the comment line
while(buf[0] != '\n'){ // search end of line
infile.read(buf,1);
}
while(isspace(buf[0])){ // Skip white space(s)
infile.read(buf,1);
}
}
// get width
bufIndex = 0;
while(bufIndex < 15 && !isspace(buf[bufIndex])){
bufIndex++;
infile.read(buf+bufIndex, 1);
}
buf[bufIndex] = NULL; // null terminated string
width = atoi(buf);
// get height
infile.read(buf,1);
while(isspace(buf[0])){ // Skip white space(s)
infile.read(buf,1);
}
bufIndex = 0;
while(bufIndex < 15 && !isspace(buf[bufIndex])){
bufIndex++;
infile.read(buf+bufIndex, 1);
}
buf[bufIndex] = NULL; // null terminated string
height = atoi(buf);
// set the image information in the struct
pic.InterLeaved = false;
pic.Width = width;
pic.Height = height;
}
else rtv = false;
return rtv;
}; // end of LoadP4Header()
int main(int argc, char* argv[])
/**************************************************************************************************
Arguments:
argv[1]: input file name
argv[2]: output file name
**************************************************************************************************/
{
ifstream infile_P4; /* input file */
ofstream outfile_P5; /* output file */
char inFileName_P4[128]; /* input file name */
char outFileName_P5[128]; /* ouput file name */
int Npixels, i;
PIC P4; //source image
PIC P5; //output file
// read the arguments
if(argc == 5)
{
strcpy(inFileName_P4, argv[1]);
strcpy(outFileName_P5, argv[2]);
}
else
{
cout<<"input Filename: ";
cin>>inFileName_P4;
cout<<"Output Filename: ";
cin>>outFileName_P5;
}
/* open input/output file */
infile_P4.open(inFileName_P4, ios::binary);
outfile_P5.open(outFileName_P5, ios::binary);
/* check input file */
if(!infile_P4)
{
cout<<"Cannot open input file "<< inFileName_P4<<endl;
return 1;
}
if (LoadP4Header(infile_P4, P4)) // load pbm (P4) image header information
{
// allocate the memory for the input image
//the dimensions of the original
P4.img = new BYTE[P4.Width*P4.Height];
LoadImage(infile_P4, P4);
// allocate memory for output images
P5.nChannel = 1;
P5.InterLeaved = false;
P5.Width = P4.Width;
P5.Height = P4.Height;
Npixels = P4.Width*P4.Height;
P5.img = new BYTE [Npixels];
cout<<Npixels<< '\n';
for (i=0; i < Npixels; i++){
P5.img
= P4.img
;
?
}//end for loop
// output PGM (P5) images
WritePGM(outfile_P5, P5);
/* Delete the pointers */
delete [] P4.img;
delete [] P5.img;
}
else
{
cout << "Error - reading PBM (P4) image header\n";
return 1;
}
/* Close file */
outfile_P5.close();
infile_P4.close();
return 0;
}

