10
10
#include < AK/Error.h>
11
11
#include < AK/IntegralMath.h>
12
12
#include < AK/Memory.h>
13
- #include < AK/MemoryStream.h>
14
13
#include < AK/NonnullOwnPtrVector.h>
15
14
#include < AK/Try.h>
15
+ #include < LibCore/MemoryStream.h>
16
16
#include < LibGfx/GIFLoader.h>
17
17
#include < string.h>
18
18
@@ -88,15 +88,13 @@ enum class GIFFormat {
88
88
GIF89a,
89
89
};
90
90
91
- static ErrorOr<GIFFormat> decode_gif_header (InputMemoryStream & stream)
91
+ static ErrorOr<GIFFormat> decode_gif_header (Core::Stream::Stream & stream)
92
92
{
93
93
static auto valid_header_87 = " GIF87a" sv;
94
94
static auto valid_header_89 = " GIF89a" sv;
95
95
96
96
Array<u8 , 6 > header;
97
- stream >> header;
98
-
99
- TRY (stream.try_handle_any_error ());
97
+ TRY (stream.read_entire_buffer (header));
100
98
101
99
if (header.span () == valid_header_87.bytes ())
102
100
return GIFFormat::GIF87a;
@@ -382,82 +380,51 @@ static ErrorOr<void> load_gif_frame_descriptors(GIFLoadingContext& context)
382
380
if (context.data_size < 32 )
383
381
return Error::from_string_literal (" Size too short for GIF frame descriptors" );
384
382
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 }));
390
384
391
- stream >> value;
392
- context.logical_screen .width = value;
385
+ TRY (decode_gif_header (*stream));
393
386
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 >>());
398
389
399
390
if (context.logical_screen .width > maximum_width_for_decoded_images || context.logical_screen .height > maximum_height_for_decoded_images) {
400
391
dbgln (" This GIF is too large for comfort: {}x{}" , context.logical_screen .width , context.logical_screen .height );
401
392
return Error::from_string_literal (" This GIF is too large for comfort" );
402
393
}
403
394
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 >());
415
398
416
399
u8 bits_per_pixel = (gcm_info & 7 ) + 1 ;
417
400
int color_map_entry_count = 1 ;
418
401
for (int i = 0 ; i < bits_per_pixel; ++i)
419
402
color_map_entry_count *= 2 ;
420
403
421
404
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 >());
426
408
context.logical_screen .color_map [i] = { r, g, b };
427
409
}
428
410
429
- TRY (stream.try_handle_any_error ());
430
-
431
411
NonnullOwnPtr<GIFImageDescriptor> current_image = make<GIFImageDescriptor>();
432
412
for (;;) {
433
- u8 sentinel = 0 ;
434
- stream >> sentinel;
435
-
436
- TRY (stream.try_handle_any_error ());
413
+ u8 sentinel = TRY (stream->read_value <u8 >());
437
414
438
415
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 >());
442
417
443
418
u8 sub_block_length = 0 ;
444
419
445
420
Vector<u8 > sub_block {};
446
421
for (;;) {
447
- stream >> sub_block_length;
448
-
449
- TRY (stream.try_handle_any_error ());
450
-
422
+ sub_block_length = TRY (stream->read_value <u8 >());
451
423
if (sub_block_length == 0 )
452
424
break ;
453
425
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)));
461
428
}
462
429
463
430
if (extension_type == 0xF9 ) {
@@ -503,24 +470,12 @@ static ErrorOr<void> load_gif_frame_descriptors(GIFLoadingContext& context)
503
470
context.images .append (move (current_image));
504
471
auto & image = context.images .last ();
505
472
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 >>());
518
477
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 >());
524
479
525
480
image.use_global_color_map = !(packed_fields & 0x80 );
526
481
image.interlaced = (packed_fields & 0x40 ) != 0 ;
@@ -529,31 +484,24 @@ static ErrorOr<void> load_gif_frame_descriptors(GIFLoadingContext& context)
529
484
size_t local_color_table_size = AK::exp2<size_t >((packed_fields & 7 ) + 1 );
530
485
531
486
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 >());
536
490
image.color_map [i] = { r, g, b };
537
491
}
538
492
}
539
493
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 >());
542
495
543
496
u8 lzw_encoded_bytes_expected = 0 ;
544
497
545
498
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 >());
550
500
if (lzw_encoded_bytes_expected == 0 )
551
501
break ;
552
502
553
503
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)));
557
505
558
506
for (int i = 0 ; i < lzw_encoded_bytes_expected; ++i) {
559
507
image.lzw_encoded_bytes .append (buffer[i]);
@@ -616,14 +564,16 @@ bool GIFImageDecoderPlugin::set_nonvolatile(bool& was_purged)
616
564
617
565
bool GIFImageDecoderPlugin::initialize ()
618
566
{
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 ();
621
571
}
622
572
623
573
ErrorOr<bool > GIFImageDecoderPlugin::sniff (ReadonlyBytes data)
624
574
{
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 ();
627
577
}
628
578
629
579
ErrorOr<NonnullOwnPtr<ImageDecoderPlugin>> GIFImageDecoderPlugin::create (ReadonlyBytes data)
0 commit comments