0

Edit: has been solved 17 Minutes after asking it.

The Problem: I didn't open the file in binary mode, and windows seems to do some weird things with files adding bytes just for the lulz.

template<uint32_t ArrayLength>
    void SaveToFile(std::shared_ptr<std::array<uint8_t, ArrayLength>> TGA, std::string name) {
        std::ofstream outputFile;
        outputFile.open("hardcoded folder path because I am lazy" + name + ".tga");
        int counter = 0;
        for (uint8_t& pixel : *TGA) {
            outputFile << pixel;
            counter++;
        }
        outputFile.close();
    }

so

this is my function. The counter is for debugging, it has no functinality.

I use this exact function twice in a row:

std::shared_ptr<std::array<uint8_t, 14422>> TGA = sim.GetTGAByteList();
SaveToFile(TGA, "test");

//sim.Step(16); 
sim.Draw();
//sim.Draw();
//sim.Draw();
//sim.Draw();
//sim.Draw();
//sim.Draw();
    
TGA = sim.GetTGAByteList();
assert(TGA->size()==14422);
SaveToFile(TGA, "test2");

as you can see, the size of TGA is exactely 14422. What sim.Draw() does is it changes the data contained within TGA, but not it's length, and the length doesn't change as seen in the assert. When I debug with the counter, stepping through the function reveals, that the loop adding one byte at a time loops exactely 14422 times.

So why in the name of god is the File 14422 bytes large when I run it the first time, and 14583 bytes when I run it the second time? and why does'nt this get fixed even if I create a completely new shared pointer to go into the savetofile function? The more often I call the sim.Draw() function, the larger the file gets, but that should not be able to change anything given that we are talking about a fixed size array. where are the additional bytes coming from?

If I drop the sim.Draw() function call, I can do wathever I want, but I can't reproduce the problem without this call.

void Draw(uint8_t configflags = 0)
    {
        if ((configflags & 0b00000001) == 0) {
            for (uint32_t i = 0; i < (*pixel_data).size(); i++) {
                uint64_t sum_of_neighbours = 0;

                bool left_edge = i % texture_width == 0;
                bool right_edge = i % texture_width == texture_width - 1;
                bool top_edge = i < texture_width;
                bool bottom_edge = i >= (texture_width * (texture_height - 1));

                if (!top_edge && !left_edge) //top left
                    sum_of_neighbours += (*pixel_data)[i - texture_width - 1];
                if (!top_edge)  //top
                    sum_of_neighbours += (*pixel_data)[i - texture_width] * 2;
                if (!top_edge && !right_edge) //top right
                    sum_of_neighbours += (*pixel_data)[i - texture_width + 1];

                if (!bottom_edge && !left_edge) //bottom left
                    sum_of_neighbours += (*pixel_data)[i + texture_width - 1];
                if (!bottom_edge) //bottom
                    sum_of_neighbours += (*pixel_data)[i + texture_width] * 2;
                if (!bottom_edge && !right_edge) //bottom right
                    sum_of_neighbours += (*pixel_data)[i + texture_width + 1];

                if (!left_edge) //left
                    sum_of_neighbours += (*pixel_data)[i - 1] * 2;
                if (!right_edge)    //right
                    sum_of_neighbours += (*pixel_data)[i + 1] * 2;

                //self
                sum_of_neighbours += (*pixel_data)[i] * 4;

                (*pixel_data)[i] = sum_of_neighbours / 16;
            }
        }

        if ((configflags & 0b00000010) == 0) {
            for (Agent& agent : agents) {


                    uint32_t index = floor(agent.position.x);
                    index += floor(agent.position.y) * texture_width;
                    (*pixel_data)[index] = -1;
                }
            }
        }

This is the Draw() function, pixel_data is basically the last 14400 bytes from the TGA array.

Did I just miss a part of the ofstream documentation? Even if I hardcode the loop in the SaveToFile() function to exit after 14422 iterations it still produces the wrong file size. Changing the file name also doesn't change anything.

  • 1
    That's because you're using an operating system that's based on MS-DOS which helpfully writes an extra byte to the file, every once in a while. You need to open the file in so-called "binary mode". – Sam Varshavchik Oct 15 '21 at 14:55
  • @SamVarshavchik It's not the operating system that does it, but the C library. CRLF in text files is just a convention, and I'm not sure the kernel even knows about it. (Although with the amount of crud that runs in kernel mode these days, I'm sure there are some components that do.) – benrg Oct 15 '21 at 17:58

0 Answers0