Skip to content

Commit c0f67a0

Browse files
nicoawesomekling
authored andcommitted
LibGfx/WebPWriter: Remove a copy in the animated frame writing code path
This code path now also compresses to memory once, and then writes to the output stream. Since the animation writer has a SeekableStream, it could compress to the stream directly and fix up offsets later. That's more complicated though, and keeping the animated and non-animated code paths similar seems nice. And the drawback is just temporary higher memory use, and the used memory is smaller than the memory needed by the input bitmap.
1 parent 0b06cbd commit c0f67a0

File tree

1 file changed

+5
-10
lines changed

1 file changed

+5
-10
lines changed

Userland/Libraries/LibGfx/ImageFormats/WebPWriter.cpp

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -434,14 +434,11 @@ ErrorOr<void> WebPAnimationWriter::add_frame(Bitmap& bitmap, int duration_ms, In
434434
if (at.x() < 0 || at.y() < 0 || at.x() + bitmap.width() > m_dimensions.width() || at.y() + bitmap.height() > m_dimensions.height())
435435
return Error::from_string_literal("Frame does not fit in animation dimensions");
436436

437-
// FIXME: The whole writing-and-reading-into-buffer over-and-over is awkward and inefficient.
438-
437+
// Since we have a SeekableStream, we could write both the VP8L chunk header and the ANMF chunk header with a placeholder size,
438+
// compress the frame data directly to the stream, and then go back and update the two sizes.
439+
// That's pretty messy though, and the compressed image data is smaller than the uncompressed bitmap passed in. So we'll buffer it.
439440
auto vp8l_data_bytes = TRY(compress_VP8L_image_data(bitmap));
440441

441-
AllocatingMemoryStream vp8l_chunk_stream;
442-
TRY(write_VP8L_chunk(vp8l_chunk_stream, bitmap.width(), bitmap.height(), true, vp8l_data_bytes));
443-
auto vp8l_chunk_bytes = TRY(vp8l_chunk_stream.read_until_eof());
444-
445442
ANMFChunkHeader chunk;
446443
chunk.frame_x = static_cast<u32>(at.x());
447444
chunk.frame_y = static_cast<u32>(at.y());
@@ -451,10 +448,8 @@ ErrorOr<void> WebPAnimationWriter::add_frame(Bitmap& bitmap, int duration_ms, In
451448
chunk.blending_method = ANMFChunkHeader::BlendingMethod::DoNotBlend;
452449
chunk.disposal_method = ANMFChunkHeader::DisposalMethod::DoNotDispose;
453450

454-
TRY(write_ANMF_chunk_header(m_stream, chunk, vp8l_chunk_bytes.size()));
455-
456-
TRY(m_stream.write_until_depleted(vp8l_chunk_bytes));
457-
VERIFY(vp8l_chunk_bytes.size() % 2 == 0);
451+
TRY(write_ANMF_chunk_header(m_stream, chunk, compute_VP8L_chunk_size(vp8l_data_bytes)));
452+
TRY(write_VP8L_chunk(m_stream, bitmap.width(), bitmap.height(), true, vp8l_data_bytes));
458453

459454
TRY(update_size_in_header());
460455

0 commit comments

Comments
 (0)