473,218 Members | 1,495 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,218 software developers and data experts.

Help with C++ program converting PBM (p4) to PPM (p5)

Hello all,

I am having a hard time seeing what I am doing wrong with a program I
am having to write that converts pbm monochrome images into a similar
pgm file. The problem I am having is understanding how to properly
convert the bit/pixel in pbm to byte/pixel in pgm. My program is very
straight forward conceptually open files, read header, read binary
data, convert to p5 in loop and then write file out. My for loop is
where I am having a problem.

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

/*** New Data Types ***/
typedef unsigned char BYTE;

struct PIC
{
unsigned int nChannel;
bool InterLeaved;
unsigned int Width, Height;
BYTE *img;
};
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);
}
void LoadImage(ifstream &infile, PIC &pic)
{
infile.read(reinterpret_cast<char *>(pic.img),
pic.Width*pic.Height*pic.nChannel);
}
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.nChannel = 1;
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; /* input file */
ofstream outfile;
char inFileName[128]; /* input file name */
char outFileName[128];
int Npixels, i, j;
PIC P4,P5;
// read the arguments
if(argc == 3)
{
strcpy(inFileName, argv[1]);
strcpy(outFileName, argv[2]);
}
else
{
cout<<"input Filename: ";
cin>>inFileName;
cout<<"Output Filename: ";
cin>>outFileName;

}

/* open input/output file */
infile.open(inFileName, ios::binary);
outfile.open(outFileName, ios::binary);

/* check input file */
if(!infile)
{
cout<<"Cannot open input file "<< inFileName<<endl;
return 1;
}

if (LoadP4Header(infile, P4)) // load pbm (P4) image header
information
{
// allocate the memory for the input image
P4.img = new BYTE[P4.Width*P4.Height*P4.nChannel/8];

LoadImage(infile, 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]; //pgm format 1 byte per pixel
int j = 0;
// de-interleaved

BYTE Results[8];

for (i=0; i < Npixels; i++){
BYTE aResult = (1-(P4.img[i]&0x80)) * 255;
BYTE bResult = (1-(P4.img[i]&0x40)) * 255;
BYTE cResult = (1-(P4.img[i]&0x20)) * 255;
BYTE dResult = (1-(P4.img[i]&0x10)) * 255;
BYTE eResult = (1-(P4.img[i]&0x08)) * 255;
BYTE fResult = (1-(P4.img[i]&0x04)) * 255;
BYTE gResult = (1-(P4.img[i]&0x02)) * 255;
BYTE hResult = (1-(P4.img[i]&0x01)) * 255;
cout<<aResult;
cout<<bResult;
cout<<cResult;
//for(y=0; y <8; y++)
}//end for outer loop

// output PGM (P5) images
WritePGM(outfile, P5);

/* Delete the pointers */
delete [] P4.img;
delete [] P5.img;
}
else
{
cout << "Error - reading PPM (P4) image header\n";
return 1;
}
/* Close file */

outfile.close();
infile.close();

return 0;
}

Sep 14 '06 #1
3 3649
On 13 Sep 2006 20:39:16 -0700 in comp.lang.c++, "Howler"
<Mr*******@gmail.comwrote,
My for loop is where I am having a problem.
....
> for (i=0; i < Npixels; i++){
BYTE aResult = (1-(P4.img[i]&0x80)) * 255;
BYTE bResult = (1-(P4.img[i]&0x40)) * 255;
BYTE cResult = (1-(P4.img[i]&0x20)) * 255;
OK, I'm not sure of the intent of your loop, so this probably isn't
quite right either. Repetitive code like that always bugs me, so
I'd go for something more like:

BYTE *inptr = P4.img, *outptr = P5.img, mask = 0x80;

for (int i=0; i < Npixels; i++){
*outptr++ = (*inptr & mask) ? 255 : 0;
mask >>= 1;
if (mask == 0) {
mask = 0x80;
inptr++;
}
}

Sep 14 '06 #2

David Harmon wrote:
On 13 Sep 2006 20:39:16 -0700 in comp.lang.c++, "Howler"
<Mr*******@gmail.comwrote,
My for loop is where I am having a problem.
...
for (i=0; i < Npixels; i++){
BYTE aResult = (1-(P4.img[i]&0x80)) * 255;
BYTE bResult = (1-(P4.img[i]&0x40)) * 255;
BYTE cResult = (1-(P4.img[i]&0x20)) * 255;

OK, I'm not sure of the intent of your loop, so this probably isn't
quite right either. Repetitive code like that always bugs me, so
I'd go for something more like:

BYTE *inptr = P4.img, *outptr = P5.img, mask = 0x80;

for (int i=0; i < Npixels; i++){
*outptr++ = (*inptr & mask) ? 255 : 0;
mask >>= 1;
if (mask == 0) {
mask = 0x80;
inptr++;
}
}
Sep 14 '06 #3

David Harmon wrote:
On 13 Sep 2006 20:39:16 -0700 in comp.lang.c++, "Howler"
<Mr*******@gmail.comwrote,
My for loop is where I am having a problem.
...
for (i=0; i < Npixels; i++){
BYTE aResult = (1-(P4.img[i]&0x80)) * 255;
BYTE bResult = (1-(P4.img[i]&0x40)) * 255;
BYTE cResult = (1-(P4.img[i]&0x20)) * 255;

OK, I'm not sure of the intent of your loop, so this probably isn't
quite right either. Repetitive code like that always bugs me, so
I'd go for something more like:

BYTE *inptr = P4.img, *outptr = P5.img, mask = 0x80;

for (int i=0; i < Npixels; i++){
*outptr++ = (*inptr & mask) ? 255 : 0;
mask >>= 1;
if (mask == 0) {
mask = 0x80;
inptr++;
}
}

David,

Thanks for the input. Your code actually fixed my problem. And the
code is much more elegant. Thanks mate.!!

Cheers!!

Sep 14 '06 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: portraitmaker | last post by:
I found some drag and drop code on the web and modified it a little b taking out some of the stuff I didn't need. This sample allows you to drag an image in a table to another positio and swaps...
5
by: Craig Keightley | last post by:
Please help, i have attached my page which worksin IE but i cannnot get the drop down menu to fucntion in firefox. Any one have any ideas why? Many Thanks Craig ...
8
by: Shamli | last post by:
Hi, Given a line segment L1 endpoints (x1, y1), (x2, y2), and distance D. I want to generate a new line segment L2 such that L2 is parallel to L1 and the distance between L1 and L2 is D. Thank...
28
by: Gaby | last post by:
Hi guys, I have this ASP code that is a little long to post so but you can download it off of http://whatthedeuce.net/Form.asp I cant find out what my error is. I know it is not in my Access...
2
by: Tomislav Fistric | last post by:
Hi all. I have very uncommon problem. I am running IIS 6.0 on 2xXEON dual core 3.06 (8 virtual CPUs) with 4 gb of Ecc ram and i get system.outofmemory exception on asp.net website. Thing is...
14
by: hall.jeff | last post by:
I wrote the following simple program to loop through our help files and fix some errors (in case you can't see the subtle RE search that's happening, we're replacing spaces in bookmarks with _'s) ...
5
by: quakersquares | last post by:
As part of a program I have to multiply two long numbers out, numbers that dont fit in any int. I feel that I have the algorithm right, but somehow the code just isnt working out and I cannot see...
3
by: memol | last post by:
/*in this part i'm giving sum data but i have error...please talk with me about my program */ #include<iostream.h> #include<string.h> #include<conio.h> void point(int*,int*,int*); void...
1
by: enonem12 | last post by:
Here is the info:Query 2: Show all orders from London. Display supplier number, part number and quantity. Query 3: Show the total number of units ordered from each supplier. Display supplier...
0
by: veera ravala | last post by:
ServiceNow is a powerful cloud-based platform that offers a wide range of services to help organizations manage their workflows, operations, and IT services more efficiently. At its core, ServiceNow...
0
by: VivesProcSPL | last post by:
Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many English-like terms and syntax in an effort to make it easy to learn, particularly for...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: jianzs | last post by:
Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.