C++ Newbie needs a c++ expert converting bits to bytes

Hello all,

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.imgIdea = P4.imgIdea;

?


}//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;
}

[5806 byte] By [Howler72] at [2007-12-24]
# 1
It's hard to analyze the whole code :(

Usually '&' operator is used for masking purpose.

if you a & a bit with 0 that bit will set to 0 and if you & with 1, the bit will remain to that old state

suppose if you want to know what's the value of 3rd bit in an 8 bit number

byte x = 135; // 0x87, binary representation 10000111
byte bMask = 3;// 0x4 binary representation 00000100

byte result = x & bMask;
In the mask the third bit is 1 and all others are 0.
So AND operation will cause all bits to set 0 except the number 3rd one because that value is 1

if result > 0, it means that the third bit is 1 and if == 0 third bit is 0

This is the basic of masking.

you can do this with other operators as well depends on your application

Sarath. at 2007-8-31 > top of Msdn Tech,Visual C++,Visual C++ Language...
# 2
I'll mark this an answered--too hard to verify Sarath's answer! :) To OP: a better way to get help is to isolate the actual code that you need to draw our attention to.
BrianKramer at 2007-8-31 > top of Msdn Tech,Visual C++,Visual C++ Language...
# 3
Thanks for the reply posts.
Howler72 at 2007-8-31 > top of Msdn Tech,Visual C++,Visual C++ Language...
# 4
Do you need help with Tsai class?
LordPraetorian at 2007-8-31 > top of Msdn Tech,Visual C++,Visual C++ Language...
# 5
Yes.
Howler72 at 2007-8-31 > top of Msdn Tech,Visual C++,Visual C++ Language...
# 6
Is my reply confusing?

if yes I shall rephrase it. :)

Sarath. at 2007-8-31 > top of Msdn Tech,Visual C++,Visual C++ Language...
# 7
Let me point out one thing.

First isolate your bug and post that part only including, what all are the data type and other required information which draws the attention to the actual problem.

Sarath. at 2007-8-31 > top of Msdn Tech,Visual C++,Visual C++ Language...
# 8
Hello all.

Thanks for responding promptly. I resolved this late last night.

Thanks!!

Howler72 at 2007-8-31 > top of Msdn Tech,Visual C++,Visual C++ Language...