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

Author Topic: [SOLVED] SFML unable to load unchanged PNG images seemingly randomly  (Read 2575 times)

0 Members and 1 Guest are viewing this topic.

UniversallyUniqueID

  • Newbie
  • *
  • Posts: 6
    • View Profile
Hello!

I observed what appears to be SFML sf::Texture sometimes succeeding, sometimes failing to load the same image, completely unchanged.

I basically have two programs, one SFML C++ program which reads an image into a texture and displays it at regular intervals, and a non-SFML Python program which creates the images and signals it to the SFML one.

Program 2 sends a unix signal (SIGUSR1) to Program 1, which handles it by loading the image into a texture. Program 2 creates and signals at intervals of 1 second.

Output (Program 1):

SIGUSR1 from 10491
updating...
Failed to load image "/tmp/windowsystem/10491/content.png". Reason: Image not of any known type, or corrupt
SIGUSR1 from 10491
updating...
Failed to load image "/tmp/windowsystem/10491/content.png". Reason: Image not of any known type, or corrupt
SIGUSR1 from 10491
updating...
SIGUSR1 from 10491
updating...
Failed to load image "/tmp/windowsystem/10491/content.png". Reason: Image not of any known type, or corrupt
SIGUSR1 from 10491
updating...
Failed to load image "/tmp/windowsystem/10491/content.png". Reason: Image not of any known type, or corrupt

I opened the files in an image viewer, and they're perfectly fine.

I thought Program 2 must be messing up the images once in a while, so I modified it to calculate the md5sum of the files each time it writes them.

Output (Program 2):

3cc40514ca5de45c6a3eecb0eb0490ff  /tmp/windowsystem/10491/content.png
3cc40514ca5de45c6a3eecb0eb0490ff  /tmp/windowsystem/10491/content.png
3cc40514ca5de45c6a3eecb0eb0490ff  /tmp/windowsystem/10491/content.png
3cc40514ca5de45c6a3eecb0eb0490ff  /tmp/windowsystem/10491/content.png
3cc40514ca5de45c6a3eecb0eb0490ff  /tmp/windowsystem/10491/content.png
3cc40514ca5de45c6a3eecb0eb0490ff  /tmp/windowsystem/10491/content.png
3cc40514ca5de45c6a3eecb0eb0490ff  /tmp/windowsystem/10491/content.png
3cc40514ca5de45c6a3eecb0eb0490ff  /tmp/windowsystem/10491/content.png

Clearly, the image is unchanged.

I'll post relevant snippets of code here:

Program 1:

// executed whenever it receives SIGUSR1
std::cout << "updating..." << std::endl;
std::string imagefname = path_join({COMMS_DIR, std::to_string(win.pid), "content.png"});
win.content_texture.loadFromFile(imagefname, sf::IntRect());
// changing empty sf::IntRect to one with the known size of the image does not help either...

Program 2:

img = Image.new("RGB", (300, 300), (255, 255, 255))
img.save(os.path.join(comms_app_dir, "content.png"))
os.system("md5sum " + os.path.join(comms_app_dir, "content.png"))

while True:
        img.save(os.path.join(comms_app_dir, "content.png"))
        os.system("md5sum " + os.path.join(comms_app_dir, "content.png"))
        time.sleep(1)
        # [... snip ...]
        os.kill(wm_pid, signal.SIGUSR1)
        # changing up the order of time.sleep() and os.kill() doesn't help...

Note that a different approach in Program 2, on the other hand, works:

while True:
        img=Image.new("RGBA", (300, 200), (255, 255, 255))
        draw = ImageDraw.Draw(img)
        draw.text((0, 0), sp.check_output(["date", "+%F %H:%M %Z"]).decode("utf-8"), (0,0,0), font=font)
        draw = ImageDraw.Draw(img)
        img.save(os.path.join(comms_app_dir, "content.png"))
        os.kill(wm_pid, signal.SIGUSR1)
        time.sleep(1)

In this second approach, a new Python image object is created each loop, but this seems to work error-free so far, despite actually modifying the image!

Output (Program 1):

SIGUSR1 from 12014
updating...
SIGUSR1 from 12014
updating...
SIGUSR1 from 12014
updating...
SIGUSR1 from 12014
updating...
SIGUSR1 from 12014
updating...
SIGUSR1 from 12014
updating...
SIGUSR1 from 12014
updating...
SIGUSR1 from 12014
updating...

(and so on for a hundred lines without errors, again at 1 second intervals)

somehow this works!

But my question is that clearly the other approach doesn't even change the file, yet why does SFML have trouble reading it?

Thanks in advance!
« Last Edit: October 29, 2019, 02:36:58 pm by UniversallyUniqueID »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: SFML unable to load unchanged PNG images seemingly randomly
« Reply #1 on: October 26, 2019, 03:12:17 pm »
Are you sure that your Python program is not generating the next image while the SFML program is still reading it?
Laurent Gomila - SFML developer

UniversallyUniqueID

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: SFML unable to load unchanged PNG images seemingly randomly
« Reply #2 on: October 26, 2019, 07:55:10 pm »
Are you sure that your Python program is not generating the next image while the SFML program is still reading it?

Hi!

Yes, I considered that.

I'm sure not because:

  (1) The Python program calculates and prints out the md5sum of the file after it writes the file, and it's unchanged. This means that by the point we've md5summed it, the file has been completely written; and the signalling occurs a full 1 second after md5 verification.

  (2) Even so, I tested adding a 5-second delay between image writing and signalling, which is far more time than it would take to write a blank 300px png, and still it gets the same errors.

Thanks.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: SFML unable to load unchanged PNG images seemingly randomly
« Reply #3 on: October 26, 2019, 09:12:23 pm »
And after signalling, what does your Python program do? Doesn't it start writing the next image right away (while the C++ program is reading the previous one)? I think your logic is wrong, there should be a delay between signalling and writing (not the other way round), so that the C++ program has enough time to read the image.
Laurent Gomila - SFML developer

UniversallyUniqueID

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: SFML unable to load unchanged PNG images seemingly randomly
« Reply #4 on: October 26, 2019, 09:31:47 pm »
And after signalling, what does your Python program do? Doesn't it start writing the next image right away (while the C++ program is reading the previous one)? I think your logic is wrong, there should be a delay between signalling and writing (not the other way round), so that the C++ program has enough time to read the image.

Ah, you're completely right. That was the cause, and making the image writing double-buffered (writing to a _new.png which is moved to the original only when free) solves it.

Thanks a lot!