Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions libvisual/libvisual/private/lv_video_png.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ namespace LV {

png_byte signature[8];
input.read (reinterpret_cast<char*> (signature), sizeof (signature));
input.seekg (saved_stream_pos);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Please add a comment to this line why we're rewinding the string here, the code does not make it obvious.
  • Is there a chance that seekg could kill an error state flag set by read above? I'm having trouble finding docs whether error flags are set until reset by the user or being auto-reset by every new API call?
  • PS: Does this have any effect on the input.seekg (saved_stream_pos); in line 93 being still needed or no longer needed?

Copy link
Member Author

@kaixiong kaixiong Jan 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Please add a comment to this line why we're rewinding the string here, the code does not make it obvious.

  • Is there a chance that seekg could kill an error state flag set by read above? I'm having trouble finding docs whether error flags are set until reset by the user or being auto-reset by every new API call?

According to this, seekg():

  1. Clears the eof flag before anything else
  2. Sets the input position only if fail() != true (i.e. either bad or fail flags are set)

So there are two failure scenarios:

  1. Partial read of signature. Both eof and fail flags are set, so seekg() does nothing. Clearly bad.
  2. Complete read of signature but stream ends immediately (no image data), so only eof is set. seekg() clears the eof and resets the input position. Okay, the decoding runs after and read errors will be caught there and then.
  • PS: Does this have any effect on the input.seekg (saved_stream_pos); in line 93 being still needed or no longer needed?

Did you mean line 98? Indeed, any read failure prior to that clean up routine will prevent the position reset, so we need to clear the fail flag with clear().

So, back to the drawing board..


if (!input) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(This reads rather weirdly to me, could we use .bad instead maybe? (https://cplusplus.com/reference/ios/ios/bad/))

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ! operator tests for the 'fail' and 'bad' flags, so they're not equivalent. However, neither accounts for EOF it seems (I thought ! did). It looks like we ought to use !input.good() 😄

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kaixiong I would like !good a lot better 👍

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hartwork, sorry bad() is indeed equivalent to !. I seriously hate iostream.

return nullptr;
}

bool is_png = !png_sig_cmp (signature, 0, sizeof (signature));

Expand Down Expand Up @@ -100,6 +105,8 @@ namespace LV {
return nullptr;
}

input.seekg (sizeof (signature), std::ios::cur);

png_set_read_fn (png_ptr, &input, handle_png_read);

png_set_sig_bytes (png_ptr, sizeof (signature));
Expand Down