From 5277ad1d6da2175ef592d8597ca774174ba82c92 Mon Sep 17 00:00:00 2001 From: Rodrigo Tobar Date: Mon, 21 Nov 2022 02:13:47 +0800 Subject: [PATCH] LibPDF: Implement Run Length Decoding This is a simple decoding process that is needed by some streams. --- Userland/Libraries/LibPDF/Filter.cpp | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/Userland/Libraries/LibPDF/Filter.cpp b/Userland/Libraries/LibPDF/Filter.cpp index 021fe65006..626cb1caa8 100644 --- a/Userland/Libraries/LibPDF/Filter.cpp +++ b/Userland/Libraries/LibPDF/Filter.cpp @@ -227,10 +227,32 @@ ErrorOr Filter::decode_flate(ReadonlyBytes bytes, int predictor, int return decode_png_prediction(buff, bytes_per_row); }; -ErrorOr Filter::decode_run_length(ReadonlyBytes) +ErrorOr Filter::decode_run_length(ReadonlyBytes bytes) { - // FIXME: Support RunLength decoding - TODO(); + constexpr size_t END_OF_DECODING = 128; + ByteBuffer buffer {}; + while (true) { + VERIFY(bytes.size() > 0); + auto length = bytes[0]; + bytes = bytes.slice(1); + if (length == END_OF_DECODING) { + VERIFY(bytes.is_empty()); + break; + } + if (length < 128) { + TRY(buffer.try_append(bytes.slice(0, length + 1))); + bytes = bytes.slice(length + 1); + } else { + VERIFY(bytes.size() > 1); + auto byte_to_append = bytes[0]; + bytes = bytes.slice(1); + size_t n_chars = 257 - length; + for (size_t i = 0; i < n_chars; ++i) { + TRY(buffer.try_append(byte_to_append)); + } + } + } + return buffer; }; ErrorOr Filter::decode_ccitt(ReadonlyBytes)