Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Problem with C++ code for image file reading for processing

Status
Not open for further replies.

CMOS

Advanced Member level 3
Joined
Jan 6, 2004
Messages
862
Helped
94
Reputation
186
Reaction score
50
Trophy points
1,308
Location
USA
Activity points
5,673
C++ File Reading Problem

Hi,
I am trying to read PGM (P5-Binary) Image file for processing using the following C++ code. The problem is that the bytes are not read properly from input file and so the output file contains junk characters only.
The code right now copies image data from one file to another. No processing is done. Can someone point out where the problem is?
Code:
//---------------------------FREE IMAGE---------------------------------
void FreeImage(int ***fimage, int N)
{
	for(int i=0; i<N; i++)
		delete (*fimage)[i];
	delete *fimage;
}

//----------------------------READ IMAGE--------------------------------
void ReadImage(char fname[], int ***fimage, int& M, int& N, int& Q)
{
	int i, j;
	char d;

	char header [100], *ptr;
	ifstream ifp;

	ifp.open(fname, ios::in);

	if (!ifp)
	{
		cout << "Can't read image: <" << fname << '>' << endl;
		getch();
		exit(1);
	}

	ifp.getline(header,100,'\n');
	if((header[0]!='P') || header[1]!='5')   /* 'P5' Formay */
	{
		cout << "Image <" << fname << "> is not in binary PGM 'P5' format." << endl;
		getch();
		exit(1);
	}

	ifp.getline(header,100,'\n');
	while(header[0]=='#')
		ifp.getline(header,100,'\n');

	M=strtol(header,&ptr,0);
	N=atoi(ptr);

	ifp.getline(header,100,'\n');

	Q=strtol(header,&ptr,0);

	*fimage = new int* [N];
	for(i=0; i<N; i++)
		(*fimage)[i] = new int[M];

	for(i=0; i<N; i++)
	{
		for(j=0; j<M; j++)
		{
			d = ifp.get();
			(*fimage)[i][j]= (int)d;
		}
	}
}

//----------------------------WriteImage--------------------------------
void WriteImage(char fname[], int **fimage, int M, int N, int Q)
{
	int i, j, c;
	ofstream ofp;

	ofp.open(fname, ios::out);
	if (!ofp)
	{
		cout << "Can't open file: " << fname << endl;
		getch();
		exit(1);
	}

	ofp << "P5" << endl << "# Comments" << endl;
	ofp << M << " " << N << endl;
	ofp << Q << endl;

	c=0;
	for (i=0; i<N; i++)
	{
		for (j=0; j<M; j++)
		{
			ofp << (char)fimage[i][j];
		}
	}

	ofp.close();

	cout << "\nFile <" << fname << "> saved.";
}

//-----------------------------Main-------------------------------------
void main(void)
{
	int i, j;
	int N, M, Q;		// N=Rows   M=Cols   Q=GreyLevels
	int **fimage;		// int **I 2-D Array of Image
	char infile[40];        // name of input file
	char outfile[40];	// name of output image file


	cout << "Enter name of *.pgm INPUT image file: ? ";
	cin  >> infile;
	cout << "Enter name of *.pgm OUTPUT image file: ? ";
	cin  >> outfile;

	ReadImage(infile, &fimage, M, N, Q);	// Memory created for fimage
	WriteImage(outfile, fimage, M, N, Q);	// Save image to file
	FreeImage(&fimage, N);           	// Clear memory
}
 

C++ File Reading Problem

If you are working with binary file using ifp.getline(header,100,'\n'); looks inappropriate .
chnage to buffer read member function .
 

Re: C++ File Reading Problem

I think you haven't understood the problem. The P5 PGM file looks somewhat like this
Code:
P5
# Created by IrfanView
20 20
255
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿ€ÿÿÿÿÿ

Where,
P5 -> Format specifier
# xxxx -> Comments
20 20 -> Size of image i.e. M x N pixels
255 -> No. of grey levels
xxxx -> raw pixel data

Thats means P5 is not completely a binary file. The first four lines contain numbers in ASCII.

The first four lines are read correctly and also stored as they are in the output file. But the Binary data which starts from 5th line appears as junk and no where related to input file.
 

C++ File Reading Problem

I never sure in what i said but there is piece of truth
that you can take into account .

have a lool to https://www.cplusplus.com/ref/iostream/ifstream/open.html
https://www.cplusplus.com/ref/iostream/istream/get.html

Once you have opened file without ifstream::binary it will format the input from file . In your example you first try to read few lines of text and then trying to read it by get() member function . But get() will read according to file open mode and also formats input .

You can test this as - make a printf of byte value read from file and compare it to the value of character in file read from your famous hexeditor - you should see there differences .

I did not check the whole code but at least this issue looks suspicious .
 

Re: C++ File Reading Problem

OK, I found the problem. I just changed ifp.open(fname, ios::in); to ifp.open(fname, ios::binary); Same was done with ofp also
Rest all is same. It works now.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top