3

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.

enter image description here

Do you have any idea of what's happening?

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

enter image description here

Adam
  • 103
  • 4
  • 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 07 '19 at 05: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 08 '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 08 '19 at 18:06
  • 1
    @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 08 '19 at 18:15

1 Answers1

2

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
user1118321
  • 3,401
  • 11
  • 14
  • 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 09 '19 at 08:06
  • 1
    Yeah, I think that would work. – user1118321 May 09 '19 at 15:58
  • 2
    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