Thread: Reading a pgm file using visual C++

  1. #1
    Registered User
    Join Date
    Nov 2015
    Posts
    5

    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?

    Code:
    #include<iostream>
    #include<string>
    #include<fstream>
    #include<sstream>
    
    usingnamespace std;
    
    int main()
    {
        int row =0, col =0, num_of_rows =0, num_of_cols =0, bits;
        ifstream infile("testfile.pgm", ios::binary);
        stringstream ss;    
        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;
    
        unsignedchar pixel;
        unsignedint pixel_value[num_of_rows][num_of_cols];
        unsignedint integral[num_of_rows][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;
            }
            cout << endl;
        }
    
        for(int i=0; i<num_of_cols;i++){//compute integral image
            integral[0][i]=integral[0][i-1]+pixel_value[0][i];      
        }   
        for(int i=0;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;
        } 
    
    infile.close();  
    return0;  
    }


    Besides, when I used visual studio 2012 to compile the above code, I used dynamic array to redefine the two arrays:

    Code:
    int**pixel_value;
    pixel_value =newint*[num_of_rows];
    for(int i=0; i<num_of_rows;i++)
        pixel_value[i]=newint[num_of_cols];
    
    int**integral;
    integral =newint*[num_of_rows];
    for(int i=0; i<num_of_rows;i++)
        integral[i]=newint[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;
        }
        cout << endl;
    }


    After I changed the code, the output text file was completely blank! It couldn't read any values from the pgm file, does anyone know how to solve the problems? I really need to compile the code on visual studio 2012.

  2. #2
    Guest
    Guest
    I haven't looked at the code yet, but please post your code again like so:
    Code:
    [code]
    Your code here...
    [/code]
    ...and make sure you use clear indentation. This will greatly improve your chances of getting help.

    Regarding Visual Studio, is there a reason you haven't switched to the 2015 Community Edition? C++11/14 support has been lagging behind a bit with Microsoft's compiler suite, so getting a recent version is a good idea in most cases.

  3. #3
    Registered User
    Join Date
    Nov 2015
    Posts
    5
    I have revised the declaration of the array and some invalid index values, but when I was compiling, an error message showed up: error 0xC0000005. I'm not what that means, is there something wrong about the memory?
    I'm using VS2012 because my instructor uses it to compile the code, so I have to make sure that my code can be compiled on VS2012.


    Code:
    #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("tsukuba.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;
    }
    cout << endl;
    }
    
    
        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;
    }

  4. #4
    Guest
    Guest
    Post the whole error.
    Code:
    if(inputLine.compare("P5") != 0) cerr << "Version error" << endl;
    cout << "Version : " << inputLine << endl;
    Are you sure the program should continue at this point if there's a "Version error"?

    I don't think you need the std::stringstream at all. std::ifstream has an overloaded >> operator as well, so you can read from it just the same.

    If you comment out everything from line 37 onward, does the code compile and do you get the correct output up to that point?

    Your teacher may want you to learn about dynamic memory allocation but manually handling (arrays of) pointers like that isn't the canonical C++ way; If you're allowed to, a std::vector would be a better choice.

    p.s. I'm not sure what your teacher is getting at with C++11 compliance. system("pause"); isn't part of ISO C++ (you can use cin.get(); as a workaround) but since you're all using VS on Windows, i somehow doubt she means that.
    Last edited by Guest; 11-19-2015 at 09:44 AM.

  5. #5
    Registered User
    Join Date
    Nov 2015
    Posts
    5
    I have revised the code, now I can run the code on visual studio 2012, and there were no segmentation faults,the header of the file can be read correctly, now the only problem is the pixel values were still not right, only the first two rows were correct.

    Code:
    #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("tsukuba.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();  
    return 0;
    }

  6. #6
    Guest
    Guest
    Can you show me the tsukuba.pgm file? Attach it if it's too big, otherwise just paste its contents between code tags. Then I can probably guess why it doesn't work.

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Here -> Reading A Pgm File Using Visual C++ - C And C++ | Dream.In.Code
    And elsewhere.
    Just so the regulars know how much effort to expend on what might already be answered somewhere else.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User
    Join Date
    Nov 2015
    Posts
    5
    The file is attached(I changed the file extensions to txt in order to upload the file).
    Attached Files Attached Files

  9. #9
    Registered User
    Join Date
    Nov 2015
    Posts
    5
    I also attached the text file I got using matlab. The pixel values of the two files become inconsistent from the middle of the third row.
    Attached Files Attached Files

  10. #10
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    Perhaps your matlab result is incorrect

    (Either way, the number of output columns is different)
    Last edited by Hodor; 11-19-2015 at 10:56 PM.

  11. #11
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Do you realize that the "P5" indicates a "binary" file? Shouldn't you be reading bytes probably using read()?

    Jim

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Switch out your C arrays to vectors and run the program in debug mode with visual studio. Likely you may find a bug or two.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to create .bat file in Visual C++? Ms Visual Studio 2010
    By rousse101 in forum Game Programming
    Replies: 0
    Last Post: 01-25-2015, 04:55 PM
  2. Replies: 3
    Last Post: 11-28-2012, 09:16 AM
  3. Image Processing - Reading GRAYLEVEL IMAGES IN VISUAL C++
    By VananGD in forum C++ Programming
    Replies: 2
    Last Post: 08-09-2012, 08:59 AM
  4. Replies: 1
    Last Post: 02-21-2012, 04:54 PM
  5. Reading from a file using Visual C++?
    By fe_yang in forum C Programming
    Replies: 1
    Last Post: 05-09-2002, 04:39 AM

Tags for this Thread