Skip to content

Commit bbe2145

Browse files
committed
fix(webp): Move write_complete_data() to close() for proper scanline order support
The WebP output plugin incorrectly assumed that scanlines would be written in sequential order, triggering the final write when y == height - 1. This violated the write_scanline API contract which allows scanlines to be written in any order (the plugin even advertises 'random_access' support). Changes: - Remove premature write_complete_data() call from write_scanline() - Move final encoding/writing to close() where it belongs - Add m_image_complete flag to track write state - Move buffer cleanup to after write_complete_data() in close() Fixes the issue where writing scanlines out of order would result in incomplete or corrupted WebP files. Signed-off-by: pmady <[email protected]>
1 parent 203d669 commit bbe2145

File tree

1 file changed

+11
-7
lines changed

1 file changed

+11
-7
lines changed

src/webp.imageio/webpoutput.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,12 @@ class WebpOutput final : public ImageOutput {
3939
unsigned int m_dither;
4040
bool m_convert_alpha; // Do we deassociate alpha?
4141
std::vector<uint8_t> m_uncompressed_image;
42+
bool m_image_complete; // Has all image data been written?
4243

4344
void init()
4445
{
45-
m_scanline_size = 0;
46+
m_scanline_size = 0;
47+
m_image_complete = false;
4648
ioproxy_clear();
4749
}
4850

@@ -238,11 +240,6 @@ WebpOutput::write_scanline(int y, int z, TypeDesc format, const void* data,
238240
std::vector<uint8_t> scratch;
239241
data = to_native_scanline(format, data, xstride, scratch, m_dither, y, z);
240242
memcpy(&m_uncompressed_image[y * m_scanline_size], data, m_scanline_size);
241-
242-
/* If this was the final scanline, we are done. */
243-
if (y == m_spec.height - 1) {
244-
return write_complete_data();
245-
}
246243
return true;
247244
}
248245

@@ -271,9 +268,16 @@ WebpOutput::close()
271268
OIIO_DASSERT(m_uncompressed_image.size());
272269
ok &= write_scanlines(m_spec.y, m_spec.y + m_spec.height, 0,
273270
m_spec.format, &m_uncompressed_image[0]);
274-
std::vector<uint8_t>().swap(m_uncompressed_image);
275271
}
276272

273+
// Write the complete image data on close, not during write_scanline.
274+
// This allows scanlines to be written in any order.
275+
if (ok && !m_image_complete && m_uncompressed_image.size()) {
276+
ok = write_complete_data();
277+
m_image_complete = true;
278+
}
279+
280+
std::vector<uint8_t>().swap(m_uncompressed_image);
277281
WebPPictureFree(&m_webp_picture);
278282
init();
279283
return ok;

0 commit comments

Comments
 (0)