tags:

views:

60

answers:

2

Im trying to write out an image file that has the following structure:

P5      //magic number
512 512 //dimension of image
255     //max value per pixel
[Image Data.....]

The standard says after max value there should be a whitespace or newline, then the image data. For whatever mysterious reason, the code below >always< adds in 2 characters at the end of the header (A carriage return and line feed). Which shifts every pixel off by 1.

Here's what I do:

   FILE *outfile; 
   outfile = fopen(filename,"w");
   int i =0, j =0;
   if(outfile==NULL || outfile == 0){
   printf("Output Failed\n");
   return;
   }
   //print header first 
   fprintf(outfile, "P5\r%d %d\r255",width,height);  
   //print out data now, all one line.
   for(i = 0; i<height; i++){
         for(j=0;j<width;j++){
              fprintf(outfile, "%c",pic[j][i]);
         }
   }

   fclose(outfile);
   printf("output to %s complete.\n", filename);          
   return;

Is there a C subtlety that I'm missing here? How do I get it to not print that extra character? I did a few experiments and I'm at a loss. Thanks for your time.

+2  A: 

I don't see 2 chars after the header when I run the above code.

I don't even see 1 char. The data starts at the very next byte after the "255" ending the header.

Is it possible that your data has pic[0][0] as a carriage return char and pic[1][0] as a line feed char?

pj_
Good point. Something is odd and OP's code is buggy (omitting the necessary whitespace) or else it's fake code. I'm guessing the latter.
R..
I'm notoriously good at writing buggy code. But this runs. Here's a picture: http://imgur.com/KLoDF.png newline and line feed are valid values for an image, but the image I'm using is bright and doesn't have very many of those.
challengerTA
+8  A: 

You must be on windows and your output file is opened in text mode. Change fopen(filename,"w") to fopen(filename,"wb") to open the file in binary mode and the problem should go away.

Hasturkun
From a standards perspective, you should always use "binary mode" anyway. The degree to which text mode is allowed to misbehave by the standard is ridiculous. Only POSIX gets it right by requiring them both to be the same and be linear binary files that end exactly at the last byte written.
R..
Perfect that fixes my alignment issue! Thanks. If you're ever in my neighborhood (Toronto). Beer is on me.
challengerTA
@R: The standard allows text mode to misbehave to the degree required to model extant text file formats on (historical) implementations. Take a look at the possibilities for text files on VMS or other record-orientated file-systems sometime: they make Windows look sensible. I agree that the Unix approach is the non-sucky one, but "always use binary mode" is equivalent to "disregard the possibility that your text-file-using program might ever run on a non-POSIX implementation". That might well be a reasonable restriction, but let's be honest about what restrictions we're making.
John Marshall