1

I am writing a program to manipulate PGM files by taking an input PGM, storing the data in a vector<unsigned char>, using the vector of data to create a new vector and so on and so forth until I use the last vector to create an output PGM file.

I've been taking it one step at a time, and I started with taking the input PGM and putting the data into a vector<unsigned char>, and then taking the original vector and outputting it into a new PGM file. Basically, copying the input into a new file. It's not working and I'm not sure why.

Here's my code:

//note: int degree is for after I start manipulating the data and dimensions will change
void outputFile(vector<unsigned char> image, int degree, int original_r, int original_c){
FILE* pgmimg;
pgmimg = fopen("pgmimg.PGM", "wb");
int temp;

int width = static_cast<int>(original_c / (pow(2, degree)));
int height = static_cast<int>(original_r / (pow(2, degree)));

fprintf(pgmimg, "P2\n");
fprintf(pgmimg, "%d %d\n", width, height);
fprintf(pgmimg, "255\n");

for (int i = 0; i < height; i++){
    for (int k = 0; k < width; k++){
        temp = image[(i*width)+k];
        
        fprintf(pgmimg, "%d ", temp);
    }
    fprintf(pgmimg, "\n");
}
fclose(pgmimg);}

int main(){
// PATH_NAME is a string defined at the beginning of the code set to the path to the input image
fstream img;
img.open(PATH_NAME, ios::in | ios::binary | ios::out);

string line;
getline(img, line);
if(!img.is_open()){
    cout << "Unable to open image" << endl;
    return 0;
}
if(!line.compare("P2")){
    cout << "Incorrect file format" << endl;
    return 0;
}

getline(img, line);
istringstream iss(line);
string row_string, col_string;
iss >> col_string;
iss >> row_string;

int original_rows = stoi(row_string);
int original_cols = stoi(col_string);

cout << original_rows << " " << original_cols << endl;
getline(img, line); //get max value

//collect data from input
int length = img.tellg();
char* buffer = new char [length];
img.read (buffer, length);
//copy data into original
vector<unsigned char> original(original_rows*original_cols);
for(int i = 0; i < original.size(); i++){
    original[i] = buffer[i];
}
outputFile(original, 0, original_rows, original_cols);
img.close();
return 0;
}

This is what I'm inputting (StackOverflow doesn't let me put a PGM, so this is the PNG version):input

This is what's being outputted in "pgmimg.PGM":output

Obviously, completely wrong (right dimensions, wrong everything else). Can anybody help me or let me know if it's a problem with reading the input or writing the output? Thanks.

esljkfgh
  • 25
  • 1
  • 5
  • Please indent your sourcecode. Also, extract a [mcve] from your code. As new user here, also take the [tour] and read [ask]. – Ulrich Eckhardt Sep 20 '20 at 19:35
  • I suspect this may be your issue: https://stackoverflow.com/questions/1744665/need-help-with-getline – Galik Sep 20 '20 at 19:47

1 Answers1

1

The input code looks wrong

int length = img.tellg();
char* buffer = new char [length];
img.read (buffer, length);

tellg is the current position in the file. That has no relation to the amount of data left to be read. Just read your data directly into your vector

vector<unsigned char> original(original_rows*original_cols);
img.read(original.data(), original.size());
john
  • 85,011
  • 4
  • 57
  • 81
  • when I use original.data() as the first argument, I get an error saying "Cannot initialize a parameter of type 'std::__1::basic_istream >::char_type *' (aka 'char *') with an rvalue of type 'std::__1::vector >::value_type *' (aka 'unsigned char *')". Anything I can do to fix it? – esljkfgh Sep 20 '20 at 20:12
  • @esljkfgh Sorry I forgot, you need to add a cast `img.read((char*)original.data(), original.size());` – john Sep 21 '20 at 04:14