@@ -58,18 +58,24 @@ namespace LV {
5858
5959 VideoPtr bitmap_load_png (std::istream& input)
6060 {
61- auto saved_stream_pos = input.tellg ();
61+ auto start_stream_pos = input.tellg ();
6262
63- png_byte signature[8 ];
64- input.read (reinterpret_cast <char *> (signature), sizeof (signature));
65- input.seekg (saved_stream_pos);
63+ // Check PNG signature.
6664
67- if (!input) {
65+ png_byte signature[8 ];
66+ if (!input.read (reinterpret_cast <char *> (signature), sizeof (signature))) {
67+ input.clear ();
68+ input.seekg (start_stream_pos);
6869 return nullptr ;
6970 }
7071
7172 bool is_png = !png_sig_cmp (signature, 0 , sizeof (signature));
7273
74+ // Clean up test by rewinding to the beginning, like we have read nothing.
75+ if (!input.seekg (start_stream_pos)) {
76+ return nullptr ;
77+ }
78+
7379 if (!is_png) {
7480 return nullptr ;
7581 }
@@ -91,11 +97,18 @@ namespace LV {
9197 return nullptr ;
9298 }
9399
100+ // Read PNG image data
101+
102+ // Skip to the first chunk, which comes right after the signature.
103+ input.seekg (start_stream_pos + std::streampos {sizeof (signature)});
104+
94105 uint8_t * pixels = nullptr ;
95106 uint8_t ** pixel_row_ptrs = nullptr ;
96107
97108 if (setjmp (png_jmpbuf (png_ptr))) {
98- input.seekg (saved_stream_pos);
109+ // Some error happened during reading. Rewind to the beginning, like we have read nothing.
110+ input.clear ();
111+ input.seekg (start_stream_pos);
99112
100113 png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
101114
@@ -105,8 +118,6 @@ namespace LV {
105118 return nullptr ;
106119 }
107120
108- input.seekg (sizeof (signature), std::ios::cur);
109-
110121 png_set_read_fn (png_ptr, &input, handle_png_read);
111122
112123 png_set_sig_bytes (png_ptr, sizeof (signature));
0 commit comments