Ver código fonte

LibCompress: Add `LZWDecoder::decode_all()`

This method takes bytes as input and decompress everything to a
ByteBuffer. It uses two control codes (clear and end of data) as
described in the GIF, TIFF and PDF specifications.
Lucas CHOLLET 1 ano atrás
pai
commit
2a5cb5becb

+ 29 - 0
Userland/Libraries/LibCompress/LZWDecoder.h

@@ -12,6 +12,7 @@
 #include <AK/Debug.h>
 #include <AK/Format.h>
 #include <AK/IntegralMath.h>
+#include <AK/MemoryStream.h>
 #include <AK/Vector.h>
 
 namespace Compress {
@@ -33,6 +34,34 @@ public:
         init_code_table();
     }
 
+    static ErrorOr<ByteBuffer> decode_all(ReadonlyBytes bytes, u8 initial_code_size, i32 offset_for_size_change = 0)
+    {
+        auto memory_stream = make<FixedMemoryStream>(bytes);
+        auto lzw_stream = make<InputStream>(MaybeOwned<Stream>(move(memory_stream)));
+        Compress::LZWDecoder lzw_decoder { MaybeOwned<InputStream> { move(lzw_stream) }, initial_code_size, offset_for_size_change };
+
+        ByteBuffer decoded;
+
+        u16 const clear_code = lzw_decoder.add_control_code();
+        u16 const end_of_data_code = lzw_decoder.add_control_code();
+
+        while (true) {
+            auto const code = TRY(lzw_decoder.next_code());
+
+            if (code == clear_code) {
+                lzw_decoder.reset();
+                continue;
+            }
+
+            if (code == end_of_data_code)
+                break;
+
+            TRY(decoded.try_append(lzw_decoder.get_output()));
+        }
+
+        return decoded;
+    }
+
     u16 add_control_code()
     {
         u16 const control_code = m_code_table.size();

+ 1 - 23
Userland/Libraries/LibPDF/Filter.cpp

@@ -198,29 +198,7 @@ PDFErrorOr<ByteBuffer> Filter::handle_lzw_and_flate_parameters(ByteBuffer buffer
 
 PDFErrorOr<ByteBuffer> Filter::decode_lzw(ReadonlyBytes bytes, int predictor, int columns, int colors, int bits_per_component, int early_change)
 {
-    auto memory_stream = make<FixedMemoryStream>(bytes);
-    auto lzw_stream = make<BigEndianInputBitStream>(MaybeOwned<Stream>(move(memory_stream)));
-    Compress::LZWDecoder lzw_decoder { MaybeOwned<BigEndianInputBitStream> { move(lzw_stream) }, 8, -early_change };
-
-    ByteBuffer decoded;
-
-    u16 const clear_code = lzw_decoder.add_control_code();
-    u16 const end_of_data_code = lzw_decoder.add_control_code();
-
-    while (true) {
-        auto const code = TRY(lzw_decoder.next_code());
-
-        if (code == clear_code) {
-            lzw_decoder.reset();
-            continue;
-        }
-
-        if (code == end_of_data_code)
-            break;
-
-        TRY(decoded.try_append(lzw_decoder.get_output()));
-    }
-
+    auto decoded = TRY(Compress::LZWDecoder<BigEndianInputBitStream>::decode_all(bytes, 8, -early_change));
     return handle_lzw_and_flate_parameters(move(decoded), predictor, columns, colors, bits_per_component);
 }