Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Maximum Image size?  (Read 1453 times)

0 Members and 1 Guest are viewing this topic.

smurf

  • Newbie
  • *
  • Posts: 36
    • View Profile
Maximum Image size?
« on: January 15, 2023, 05:11:40 am »
I'm hitting the limits of the SFML Image class, and wondering if theres any easy workarounds.

I was trying to export a texture to a PNG using rtexture.getTexture().copyToImage().saveToFile("toto.png");

But no image was being written to disk. Debugging I found that the pixels array member of the Image class is having an overflow exception. My texture is 30,000 by 30,000 in size. Yes I realize this is crazy but I wanted to export my entire game map to a PNG for my reference and debugging purposes.

Doing the math I see that 30,000 * 30,000 * 4 (4 bits per pixel) = a number larger than a 32 bit integer can handle, so this is probably the issue. I confirmed this by just directly creating an image that large with the Image constructor, so the Texture class and graphics card are not even in the picture. Same issue.

So I know its a long-shot but is there any chance of having the Image class using 64 bit ints internally, or having a new LargeImage class or something?



kojack

  • Sr. Member
  • ****
  • Posts: 343
  • C++/C# game dev teacher.
    • View Profile
Re: Maximum Image size?
« Reply #1 on: January 16, 2023, 03:17:12 am »
I'm assuming you are doing a 32 bit build of the project.
SFML's Image class uses a Vector2u to store the resolution. This can theoretically handle 4 billion x 4 billion resolution. But it uses an std::vector of bytes to store the pixel data. In 32 bit projects, std::vector is limited to 4 billion (roughly) items. At 1 byte each, that's 4GB of ram.

A 30000x30000 image at 4 bytes per pixel is 3.4GB. That sounds ok, but 32bit apps have only 4GB total address space for everything, not just the image. Plus if you are on windows, 32 bit apps are only allowed to access 2GB normally, or a bit over 3GB if you enable the large address aware flag.

In a 64 bit project, I just made an 80000x80000 SFML Image and it was fine, which is 24GB of ram (I've got 32GB on my PC).

There's another issue though.
SFML uses STB Image (3rd party library by Sean Barrett) for image loading/saving. From what I can see, STB Image is made for 32bit. For example its PNG saving code returns the total size in memory of the data to save as a signed int, so it would be limited to 2GB size before things go wrong. It also has to allocate more ram as part of the saving on top of the already large amount in SFML.
I can get a PNG to save with 20000x20000. At 25000x25000 and above it fails with an error. At 40000x40000 and above it crashes the program.

So... doing a 64bit build will fix the image class. But you'll need to add alternative saving code to handle those sizes.