Matei
Matei

Reputation: 372

fwrite() not writing entire ppm file

So, I'm struggling with a homework which asks me to anti-alias a photo. But that's not the point of my question. The files are .ppm ppm format. I read it, using fread (it's color so I need to read rgb).

fread(tmp, 3 * sizeof(char), maxWidth * maxHeight, f)

where

tmp = (char *)malloc(width * height * 3 * sizeof(char));

I cast the tmp to short int (I need to do some work on the resulting matrix):

for(i=0; i < width * height; i++){
    values[i] = (short int)tmp[i];
}

values is defined as short int:

values =  (short int*) malloc(width * height * sizeof(short int));

The thing is that I just wanted to make a test. Read the image, transform it to int, transform it back to char, write the image. In this stage, only 1/4 of the image is written and I don't know why. I read the documentation for fwrite, but I cannot find out what I am doing wrong. Transform the image back (tmp2 allocated as img):

for(i=0; i < width * height; i++){
    tmp2[i] = (char)values[i];
}

fwrite(tmp2, 3 * sizeof(char), width * height, g);

Am I using fwrite correctly? Maybe someone struggled with this too and knows how to answer.

Upvotes: 2

Views: 869

Answers (1)

Paul Ogilvie
Paul Ogilvie

Reputation: 25286

A short int is 16 bits, or two bytes. In:

for(i=0; i < width * height; i++){
    values[i] = (short int)tmp[i];
}

you are only copying 2/3rd of the image data (and there is more wrong as each byte gets copied twice: i is incremented with 1 byte and the cast takes two bytes, one of which was copied already). Then in:

for(i=0; i < width * height; i++){
    tmp2[i] = (char)values[i];
}

you are copying only half of values (the first byte of each short), or 1/3rd of the image. Then in:

fwrite(tmp2, 3 * sizeof(char), width * height, g);

you are writing the correct mount of bytes, but the file contains only 1/3rd of the image (and a lot of garbage or zeroes).

I leave fixing this to you.

Upvotes: 1

Related Questions