3
$\begingroup$

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

$\endgroup$
4
  • $\begingroup$ 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. $\endgroup$ Commented May 7, 2019 at 5:16
  • $\begingroup$ 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? $\endgroup$
    – Simon F
    Commented May 8, 2019 at 13:40
  • $\begingroup$ @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. $\endgroup$ Commented May 8, 2019 at 18:06
  • 1
    $\begingroup$ @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? $\endgroup$ Commented May 8, 2019 at 18:15

1 Answer 1

2
$\begingroup$

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
$\endgroup$
3
  • $\begingroup$ 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. $\endgroup$
    – Simon F
    Commented May 9, 2019 at 8:06
  • 1
    $\begingroup$ Yeah, I think that would work. $\endgroup$ Commented May 9, 2019 at 15:58
  • 2
    $\begingroup$ Thanks to both of you. Changing the opening the file with ofs.open("./example.ppm", std::ofstream::binary); did it. $\endgroup$ Commented May 10, 2019 at 15:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.