mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 03:27:45 +00:00
LibGfx+LibPDF: Use LibCompress' implementation of the PackBits decoder
No need to have these three copies :^)
This commit is contained in:
parent
d748edd994
commit
f389c1cdba
3 changed files with 7 additions and 95 deletions
|
@ -9,6 +9,7 @@
|
||||||
#include <AK/Endian.h>
|
#include <AK/Endian.h>
|
||||||
#include <AK/FixedArray.h>
|
#include <AK/FixedArray.h>
|
||||||
#include <AK/IntegralMath.h>
|
#include <AK/IntegralMath.h>
|
||||||
|
#include <LibCompress/PackBitsDecoder.h>
|
||||||
#include <LibGfx/FourCC.h>
|
#include <LibGfx/FourCC.h>
|
||||||
#include <LibGfx/ImageFormats/ILBMLoader.h>
|
#include <LibGfx/ImageFormats/ILBMLoader.h>
|
||||||
|
|
||||||
|
@ -246,39 +247,7 @@ static ErrorOr<ByteBuffer> uncompress_byte_run(ReadonlyBytes data, ILBMLoadingCo
|
||||||
if (plane_data_size > NumericLimits<u32>::max() || ceil_div(plane_data_size, 127ul) > length)
|
if (plane_data_size > NumericLimits<u32>::max() || ceil_div(plane_data_size, 127ul) > length)
|
||||||
return Error::from_string_literal("Uncompressed data size too large");
|
return Error::from_string_literal("Uncompressed data size too large");
|
||||||
|
|
||||||
auto plane_data = TRY(ByteBuffer::create_uninitialized(plane_data_size));
|
auto plane_data = TRY(Compress::PackBits::decode_all(data, plane_data_size));
|
||||||
|
|
||||||
u32 index = 0;
|
|
||||||
u32 read_bytes = 0;
|
|
||||||
// Uncompressing is done once we've read all buffer or plane buffer has been fully filled
|
|
||||||
while (read_bytes < length && index < plane_data_size) {
|
|
||||||
auto const byte = static_cast<i8>(data[read_bytes++]);
|
|
||||||
if (byte >= -127 && byte <= -1) {
|
|
||||||
// read next byte
|
|
||||||
if (read_bytes == data.size())
|
|
||||||
return Error::from_string_literal("Malformed compressed data");
|
|
||||||
|
|
||||||
u8 next_byte = data[read_bytes++];
|
|
||||||
if (index + -byte >= plane_data.size())
|
|
||||||
return Error::from_string_literal("Malformed compressed data");
|
|
||||||
|
|
||||||
for (u16 i = 0; i < -byte + 1; ++i) {
|
|
||||||
plane_data[index++] = next_byte;
|
|
||||||
}
|
|
||||||
} else if (byte >= 0) {
|
|
||||||
if (index + byte >= plane_data_size || read_bytes + byte >= length)
|
|
||||||
return Error::from_string_literal("Malformed compressed data");
|
|
||||||
|
|
||||||
for (u16 i = 0; i < byte + 1; ++i) {
|
|
||||||
plane_data[index] = data[read_bytes];
|
|
||||||
read_bytes++;
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index != plane_data_size)
|
|
||||||
return Error::from_string_literal("Unexpected end of chunk while decompressing data");
|
|
||||||
|
|
||||||
return plane_data;
|
return plane_data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <AK/Endian.h>
|
#include <AK/Endian.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
#include <LibCompress/LZWDecoder.h>
|
#include <LibCompress/LZWDecoder.h>
|
||||||
|
#include <LibCompress/PackBitsDecoder.h>
|
||||||
#include <LibGfx/ImageFormats/CCITTDecoder.h>
|
#include <LibGfx/ImageFormats/CCITTDecoder.h>
|
||||||
#include <LibGfx/ImageFormats/TIFFMetadata.h>
|
#include <LibGfx/ImageFormats/TIFFMetadata.h>
|
||||||
|
|
||||||
|
@ -284,44 +285,8 @@ private:
|
||||||
ByteBuffer decoded_bytes {};
|
ByteBuffer decoded_bytes {};
|
||||||
|
|
||||||
auto decode_packbits_strip = [&](u32 num_bytes) -> ErrorOr<ReadonlyBytes> {
|
auto decode_packbits_strip = [&](u32 num_bytes) -> ErrorOr<ReadonlyBytes> {
|
||||||
auto strip_stream = make<FixedMemoryStream>(TRY(m_stream->read_in_place<u8 const>(num_bytes)));
|
auto const encoded_bytes = TRY(m_stream->read_in_place<u8 const>(num_bytes));
|
||||||
|
decoded_bytes = TRY(Compress::PackBits::decode_all(encoded_bytes));
|
||||||
decoded_bytes.clear();
|
|
||||||
|
|
||||||
Optional<i8> n {};
|
|
||||||
Optional<u8> saved_byte {};
|
|
||||||
|
|
||||||
while (strip_stream->remaining() > 0 || saved_byte.has_value()) {
|
|
||||||
if (!n.has_value())
|
|
||||||
n = TRY(strip_stream->read_value<i8>());
|
|
||||||
|
|
||||||
if (n.value() >= 0 && !saved_byte.has_value()) {
|
|
||||||
n.value() = n.value() - 1;
|
|
||||||
if (n.value() == -1)
|
|
||||||
n.clear();
|
|
||||||
|
|
||||||
decoded_bytes.append(TRY(strip_stream->read_value<u8>()));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n.value() == -128) {
|
|
||||||
n.clear();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!saved_byte.has_value())
|
|
||||||
saved_byte = TRY(strip_stream->read_value<u8>());
|
|
||||||
|
|
||||||
n.value() = n.value() + 1;
|
|
||||||
|
|
||||||
decoded_bytes.append(*saved_byte);
|
|
||||||
|
|
||||||
if (n == 1) {
|
|
||||||
saved_byte.clear();
|
|
||||||
n.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return decoded_bytes;
|
return decoded_bytes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <AK/Hex.h>
|
#include <AK/Hex.h>
|
||||||
#include <LibCompress/Deflate.h>
|
#include <LibCompress/Deflate.h>
|
||||||
#include <LibCompress/LZWDecoder.h>
|
#include <LibCompress/LZWDecoder.h>
|
||||||
|
#include <LibCompress/PackBitsDecoder.h>
|
||||||
#include <LibGfx/ImageFormats/JPEGLoader.h>
|
#include <LibGfx/ImageFormats/JPEGLoader.h>
|
||||||
#include <LibGfx/ImageFormats/PNGLoader.h>
|
#include <LibGfx/ImageFormats/PNGLoader.h>
|
||||||
#include <LibPDF/CommonNames.h>
|
#include <LibPDF/CommonNames.h>
|
||||||
|
@ -210,30 +211,7 @@ PDFErrorOr<ByteBuffer> Filter::decode_flate(ReadonlyBytes bytes, int predictor,
|
||||||
|
|
||||||
PDFErrorOr<ByteBuffer> Filter::decode_run_length(ReadonlyBytes bytes)
|
PDFErrorOr<ByteBuffer> Filter::decode_run_length(ReadonlyBytes bytes)
|
||||||
{
|
{
|
||||||
constexpr size_t END_OF_DECODING = 128;
|
return TRY(Compress::PackBits::decode_all(bytes, OptionalNone {}, Compress::PackBits::CompatibilityMode::PDF));
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PDFErrorOr<ByteBuffer> Filter::decode_ccitt(ReadonlyBytes)
|
PDFErrorOr<ByteBuffer> Filter::decode_ccitt(ReadonlyBytes)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue