Wrong color in .ppm file

I'm going through the rasterizer tutorial from Scratchapixel, but I encountered a problem with the generation of the .ppm file. Since something was off, I reduced the example to the bare minimum, so I currently simply generate a 512x512 image of a plain color.

#include <fstream>

using Rgb = unsigned char[3];
int main()
{
const uint32_t w = 512;
const uint32_t h = 512;

Rgb *framebuffer = new Rgb[w * h];
for (uint32_t j = 0; j < h; ++j) {
for (uint32_t i = 0; i < w; ++i) {
framebuffer[j * w + i][0] = static_cast<unsigned char>(255);
framebuffer[j * w + i][1] = static_cast<unsigned char>(0);
framebuffer[j * w + i][2] = static_cast<unsigned char>(0);
}
}

std::ofstream ofs;
ofs.open("./example.ppm");
ofs << "P6\n" << w << " " << h << "\n255\n";
ofs.write((char*)framebuffer, w * h * 3);
ofs.close();

delete[] framebuffer;

return 0;
}


The code above should generate a red square image, but if I open the file with Gimp, I get a green image.

Do you have any idea of what's happening?

EDIT: This is the .ppm file with a hex editor:

• Perhaps something is wrong (or set oddly) in Gimp? On macOS in the Finder and in Preview.app, it shows up as solid red, as expected. – user1118321 May 7 '19 at 5:16
• I couldn't see a link to the binary file to check myself, but can you open it in a hex editor just to make sure you haven't shifted the data by a byte? – Simon F May 8 '19 at 13:40
• @user1118321 Thanks for pointing this out. How could you manage to open the file with the Preview.app? I'm trying but the app doesn't show any window. – Francis Moy May 8 '19 at 18:06
• @SimonF I added a screenshot of the binary file with an hex editor, and as far as I can tell, it should be fine... Don't you think? – Francis Moy May 8 '19 at 18:15

The issue is that on your system, writing out "\n" is writing out 0x0D0A, whereas on my system, it's only writing out 0x0A. If you explicitly write out 0x0A instead of "\n" I think it will work for you.

Here's a hex dump on macOS Mojave:

50 36 0A 35
31 32 20 35
31 32 0A 32
35 35 0A
FF 00 00 // <- pixels start here
FF 00 00
FF 00 00
FF 00 00
FF 00 00
FF 00 00

• I'm not too familiar with c++ file i/o , but in c maybe it's the difference between creating the file with textmode, fopen(fname, "w"), VS binary, fopen(fname, "wb"). It needs to be a binary file. – Simon F May 9 '19 at 8:06
• Yeah, I think that would work. – user1118321 May 9 '19 at 15:58
• Thanks to both of you. Changing the opening the file with ofs.open("./example.ppm", std::ofstream::binary); did it. – Francis Moy May 10 '19 at 15:44