Skip to content

Commit 5aaa39e

Browse files
krkkawesomekling
authored andcommitted
LibGfx: Port GIFLoader to Core::Stream
1 parent 86b1b49 commit 5aaa39e

File tree

1 file changed

+35
-85
lines changed

1 file changed

+35
-85
lines changed

Userland/Libraries/LibGfx/GIFLoader.cpp

Lines changed: 35 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
#include <AK/Error.h>
1111
#include <AK/IntegralMath.h>
1212
#include <AK/Memory.h>
13-
#include <AK/MemoryStream.h>
1413
#include <AK/NonnullOwnPtrVector.h>
1514
#include <AK/Try.h>
15+
#include <LibCore/MemoryStream.h>
1616
#include <LibGfx/GIFLoader.h>
1717
#include <string.h>
1818

@@ -88,15 +88,13 @@ enum class GIFFormat {
8888
GIF89a,
8989
};
9090

91-
static ErrorOr<GIFFormat> decode_gif_header(InputMemoryStream& stream)
91+
static ErrorOr<GIFFormat> decode_gif_header(Core::Stream::Stream& stream)
9292
{
9393
static auto valid_header_87 = "GIF87a"sv;
9494
static auto valid_header_89 = "GIF89a"sv;
9595

9696
Array<u8, 6> header;
97-
stream >> header;
98-
99-
TRY(stream.try_handle_any_error());
97+
TRY(stream.read_entire_buffer(header));
10098

10199
if (header.span() == valid_header_87.bytes())
102100
return GIFFormat::GIF87a;
@@ -382,82 +380,51 @@ static ErrorOr<void> load_gif_frame_descriptors(GIFLoadingContext& context)
382380
if (context.data_size < 32)
383381
return Error::from_string_literal("Size too short for GIF frame descriptors");
384382

385-
InputMemoryStream stream { { context.data, context.data_size } };
386-
387-
TRY(decode_gif_header(stream));
388-
389-
LittleEndian<u16> value;
383+
auto stream = TRY(Core::Stream::FixedMemoryStream::construct(ReadonlyBytes { context.data, context.data_size }));
390384

391-
stream >> value;
392-
context.logical_screen.width = value;
385+
TRY(decode_gif_header(*stream));
393386

394-
stream >> value;
395-
context.logical_screen.height = value;
396-
397-
TRY(stream.try_handle_any_error());
387+
context.logical_screen.width = TRY(stream->read_value<LittleEndian<u16>>());
388+
context.logical_screen.height = TRY(stream->read_value<LittleEndian<u16>>());
398389

399390
if (context.logical_screen.width > maximum_width_for_decoded_images || context.logical_screen.height > maximum_height_for_decoded_images) {
400391
dbgln("This GIF is too large for comfort: {}x{}", context.logical_screen.width, context.logical_screen.height);
401392
return Error::from_string_literal("This GIF is too large for comfort");
402393
}
403394

404-
u8 gcm_info = 0;
405-
stream >> gcm_info;
406-
407-
TRY(stream.try_handle_any_error());
408-
409-
stream >> context.background_color_index;
410-
TRY(stream.try_handle_any_error());
411-
412-
u8 pixel_aspect_ratio = 0;
413-
stream >> pixel_aspect_ratio;
414-
TRY(stream.try_handle_any_error());
395+
auto gcm_info = TRY(stream->read_value<u8>());
396+
context.background_color_index = TRY(stream->read_value<u8>());
397+
[[maybe_unused]] auto pixel_aspect_ratio = TRY(stream->read_value<u8>());
415398

416399
u8 bits_per_pixel = (gcm_info & 7) + 1;
417400
int color_map_entry_count = 1;
418401
for (int i = 0; i < bits_per_pixel; ++i)
419402
color_map_entry_count *= 2;
420403

421404
for (int i = 0; i < color_map_entry_count; ++i) {
422-
u8 r = 0;
423-
u8 g = 0;
424-
u8 b = 0;
425-
stream >> r >> g >> b;
405+
u8 r = TRY(stream->read_value<u8>());
406+
u8 g = TRY(stream->read_value<u8>());
407+
u8 b = TRY(stream->read_value<u8>());
426408
context.logical_screen.color_map[i] = { r, g, b };
427409
}
428410

429-
TRY(stream.try_handle_any_error());
430-
431411
NonnullOwnPtr<GIFImageDescriptor> current_image = make<GIFImageDescriptor>();
432412
for (;;) {
433-
u8 sentinel = 0;
434-
stream >> sentinel;
435-
436-
TRY(stream.try_handle_any_error());
413+
u8 sentinel = TRY(stream->read_value<u8>());
437414

438415
if (sentinel == '!') {
439-
u8 extension_type = 0;
440-
stream >> extension_type;
441-
TRY(stream.try_handle_any_error());
416+
u8 extension_type = TRY(stream->read_value<u8>());
442417

443418
u8 sub_block_length = 0;
444419

445420
Vector<u8> sub_block {};
446421
for (;;) {
447-
stream >> sub_block_length;
448-
449-
TRY(stream.try_handle_any_error());
450-
422+
sub_block_length = TRY(stream->read_value<u8>());
451423
if (sub_block_length == 0)
452424
break;
453425

454-
u8 dummy = 0;
455-
for (u16 i = 0; i < sub_block_length; ++i) {
456-
stream >> dummy;
457-
sub_block.append(dummy);
458-
}
459-
460-
TRY(stream.try_handle_any_error());
426+
TRY(sub_block.try_resize(sub_block.size() + sub_block_length));
427+
TRY(stream->read_entire_buffer(sub_block.span().slice_from_end(sub_block_length)));
461428
}
462429

463430
if (extension_type == 0xF9) {
@@ -503,24 +470,12 @@ static ErrorOr<void> load_gif_frame_descriptors(GIFLoadingContext& context)
503470
context.images.append(move(current_image));
504471
auto& image = context.images.last();
505472

506-
LittleEndian<u16> tmp;
507-
508-
u8 packed_fields { 0 };
509-
510-
stream >> tmp;
511-
image.x = tmp;
512-
513-
stream >> tmp;
514-
image.y = tmp;
515-
516-
stream >> tmp;
517-
image.width = tmp;
473+
image.x = TRY(stream->read_value<LittleEndian<u16>>());
474+
image.y = TRY(stream->read_value<LittleEndian<u16>>());
475+
image.width = TRY(stream->read_value<LittleEndian<u16>>());
476+
image.height = TRY(stream->read_value<LittleEndian<u16>>());
518477

519-
stream >> tmp;
520-
image.height = tmp;
521-
522-
stream >> packed_fields;
523-
TRY(stream.try_handle_any_error());
478+
auto packed_fields = TRY(stream->read_value<u8>());
524479

525480
image.use_global_color_map = !(packed_fields & 0x80);
526481
image.interlaced = (packed_fields & 0x40) != 0;
@@ -529,31 +484,24 @@ static ErrorOr<void> load_gif_frame_descriptors(GIFLoadingContext& context)
529484
size_t local_color_table_size = AK::exp2<size_t>((packed_fields & 7) + 1);
530485

531486
for (size_t i = 0; i < local_color_table_size; ++i) {
532-
u8 r = 0;
533-
u8 g = 0;
534-
u8 b = 0;
535-
stream >> r >> g >> b;
487+
u8 r = TRY(stream->read_value<u8>());
488+
u8 g = TRY(stream->read_value<u8>());
489+
u8 b = TRY(stream->read_value<u8>());
536490
image.color_map[i] = { r, g, b };
537491
}
538492
}
539493

540-
stream >> image.lzw_min_code_size;
541-
TRY(stream.try_handle_any_error());
494+
image.lzw_min_code_size = TRY(stream->read_value<u8>());
542495

543496
u8 lzw_encoded_bytes_expected = 0;
544497

545498
for (;;) {
546-
stream >> lzw_encoded_bytes_expected;
547-
548-
TRY(stream.try_handle_any_error());
549-
499+
lzw_encoded_bytes_expected = TRY(stream->read_value<u8>());
550500
if (lzw_encoded_bytes_expected == 0)
551501
break;
552502

553503
Array<u8, 256> buffer;
554-
stream >> buffer.span().trim(lzw_encoded_bytes_expected);
555-
556-
TRY(stream.try_handle_any_error());
504+
TRY(stream->read_entire_buffer(buffer.span().trim(lzw_encoded_bytes_expected)));
557505

558506
for (int i = 0; i < lzw_encoded_bytes_expected; ++i) {
559507
image.lzw_encoded_bytes.append(buffer[i]);
@@ -616,14 +564,16 @@ bool GIFImageDecoderPlugin::set_nonvolatile(bool& was_purged)
616564

617565
bool GIFImageDecoderPlugin::initialize()
618566
{
619-
InputMemoryStream stream { { m_context->data, m_context->data_size } };
620-
return !decode_gif_header(stream).is_error();
567+
auto stream_or_error = Core::Stream::FixedMemoryStream::construct(ReadonlyBytes { m_context->data, m_context->data_size });
568+
if (stream_or_error.is_error())
569+
return false;
570+
return !decode_gif_header(*stream_or_error.value()).is_error();
621571
}
622572

623573
ErrorOr<bool> GIFImageDecoderPlugin::sniff(ReadonlyBytes data)
624574
{
625-
InputMemoryStream stream { { data.data(), data.size() } };
626-
return !decode_gif_header(stream).is_error();
575+
auto stream = TRY(Core::Stream::FixedMemoryStream::construct(data));
576+
return !decode_gif_header(*stream).is_error();
627577
}
628578

629579
ErrorOr<NonnullOwnPtr<ImageDecoderPlugin>> GIFImageDecoderPlugin::create(ReadonlyBytes data)

0 commit comments

Comments
 (0)