Reading a pgm file using visual C++

I want to read the pixel values from a pgm file, then compute the integral image and save the result to a text file. At first I used Dev C++ to compile my code, but the pixel values have segmentation faults(Only the first three rows are correct). My instructor said there were two small bugs in my code which caused segmentation faults, but I don't know where the bugs are. She also said that she cannot compile my code on visual studio, she wants me to send her a C++11 compliant version, what does that mean?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>

using namespace std;

int main()
{
    int row = 0, col = 0, num_of_rows = 0, num_of_cols = 0;
    stringstream ss;    
    ifstream infile("testfile.pgm", ios::binary);

    string inputLine = "";

    getline(infile,inputLine);      // read the first line : P5
    if(inputLine.compare("P5") != 0) cerr << "Version error" << endl;
    cout << "Version : " << inputLine << endl;
    
    getline(infile,inputLine);  // read the second line : comment
    cout << "Comment : " << inputLine << endl;

    ss << infile.rdbuf();   //read the third line : width and height
    ss >> num_of_cols >> num_of_rows;
    cout << num_of_cols << " columns and " << num_of_rows << " rows" << endl;

    int max_val;  //maximum intensity value : 255
    ss >> max_val;
    cout<<max_val;
    
    unsigned char pixel;

	int **pixel_value = new int*[num_of_rows];
    for(int i = 0; i < num_of_rows; ++i) {
        pixel_value[i] = new int[num_of_cols];
    }

	int **integral = new int*[num_of_rows];
    for(int i = 0; i < num_of_rows; ++i) {
        integral[i] = new int[num_of_cols];
    }

    for (row = 0; row < num_of_rows; row++){    //record the pixel values
        for (col = 0; col < num_of_cols; col++){
             ss >> pixel;
             pixel_value[row][col]= pixel;
        }
    }
    
    
	integral[0][0]=pixel_value[0][0];    
	for(int i=1; i<num_of_cols;i++){            //compute integral image
		integral[0][i]=integral[0][i-1]+pixel_value[0][i];		
	}	
	for (int i=1;i<num_of_rows; i++){
		integral[i][0]=integral[i-1][0]+pixel_value[i][0];
	}
		for (int i = 1; i < num_of_rows; i++){  
    	for (int j = 1; j < num_of_cols; j++){
    	integral[i][j] = integral[i - 1 ][j] + integral [i][j - 1] - integral[i - 1] [j - 1] + pixel_value[i][j]; 		
		}
	}
	
    ofstream output1("pixel_value.txt");  // output the intensity values of the pgm file
    for (int k=0; k<num_of_rows; k++)
    {
        for (int r=0; r<num_of_cols; r++)
        {
            output1 << pixel_value[k][r] << " ";
        }
        output1 << ";" << endl;
    }
    
    ofstream output2("integral_value.txt");    // output the integral image
    for (int a=0; a<num_of_rows; a++)
    {
        for (int b=0; b<num_of_cols; b++)
        {
            output2 << integral[a][b] << " ";
        }
        output2 << ";" << endl;
    }

	for(int i = 0; i < num_of_rows; ++i) {
        delete [] pixel_value[i];
	}
    delete [] pixel_value;

	for(int i = 0; i < num_of_rows; ++i) {
        delete [] integral[i];
	}
    delete [] integral;

infile.close();  
system("pause");
return 0;
}

Last edited on
What are you trying to do on line 22?

Better use vector instead of dynamically created arrays.
Dynamic arrays are fine, and you handle them correctly.

Segmentation faults are caused by trying to access memory outside of array bounds. You do that on lines 43 and 46. integral[...][0-1] == integral[...][-1] == segmentation fault. Fix it by considering what value i starts with on lines 42 and 45.

You have two other major errors that will confuse you:

1) You are obtaining the pixel value as a char. However, the value of the character '0', for example, is not zero. You should be inputting the values as ints!

2) You don't need that streamstream. Get rid of it and just read directly from your infile.

Hope this helps.
Thanks for the reply. I have revised lines 43 and 46 and the dynamic arrays in the above code, now it can read the header correctly, showing the right version, comment, and size. But the pixel values of the pgm file were still wrong. Only the first two rows were correct.

*I used matlab to read the pgm file before, the pixel values read by matlab don't match with the pixel values read by visual c++ (only the first two rows are the same), is it possible that the pixel values would be different when using different software?
Last edited on
Assuming you also read the rest of my answer and fixed the pixel color input, then I do not know why you would get only two lines correctly and the rest as garbage.
Topic archived. No new replies allowed.