@@ -135,7 +135,7 @@ struct Component {
135
135
u8 vsample_factor { 1 }; // Vi, Vertical sampling factor
136
136
u8 qtable_id { 0 }; // Tqi, Quantization table destination selector
137
137
138
- // The JPEG specification does not specify which component correspond to
138
+ // The JPEG specification does not specify which component corresponds to
139
139
// Y, Cb or Cr. This field (actually the index in the parent Vector) will
140
140
// act as an authority to determine the *real* component.
141
141
// Please note that this is implementation specific.
@@ -547,30 +547,39 @@ static inline ErrorOr<Marker> read_marker_at_cursor(Stream& stream)
547
547
548
548
static ErrorOr<void > read_start_of_scan (AK::SeekableStream& stream, JPEGLoadingContext& context)
549
549
{
550
+ // B.2.3 - Scan header syntax
551
+
550
552
if (context.state < JPEGLoadingContext::State::FrameDecoded) {
551
553
dbgln_if (JPEG_DEBUG, " {}: SOS found before reading a SOF!" , TRY (stream.tell ()));
552
554
return Error::from_string_literal (" SOS found before reading a SOF" );
553
555
}
554
556
555
557
u16 bytes_to_read = TRY (stream.read_value <BigEndian<u16 >>()) - 2 ;
556
558
TRY (ensure_bounds_okay (TRY (stream.tell ()), bytes_to_read, context.data_size ));
557
- [[maybe_unused]] u8 const component_count = TRY (stream.read_value <u8 >());
559
+ u8 const component_count = TRY (stream.read_value <u8 >());
558
560
559
561
Scan current_scan;
560
562
563
+ Optional<u8 > last_read;
564
+ u8 component_read = 0 ;
561
565
for (auto & component : context.components ) {
562
- u8 component_id = TRY (stream.read_value <u8 >());
566
+ // See the Csj paragraph:
567
+ // [...] the ordering in the scan header shall follow the ordering in the frame header.
568
+ if (component_read == component_count)
569
+ break ;
563
570
564
- if (component.id != component_id) {
565
- dbgln (" JPEG decode failed (component.id != component_id)" );
566
- return Error::from_string_literal (" JPEG decode failed (component.id != component_id)" );
567
- }
571
+ if (!last_read.has_value ())
572
+ last_read = TRY (stream.read_value <u8 >());
573
+
574
+ if (component.id != *last_read)
575
+ continue ;
568
576
569
577
u8 table_ids = TRY (stream.read_value <u8 >());
570
578
571
- ScanComponent scan_component { component, static_cast <u8 >(table_ids >> 4 ), static_cast <u8 >(table_ids & 0x0F ) } ;
579
+ current_scan. components . empend ( component, static_cast <u8 >(table_ids >> 4 ), static_cast <u8 >(table_ids & 0x0F )) ;
572
580
573
- current_scan.components .append (scan_component);
581
+ component_read++;
582
+ last_read.clear ();
574
583
}
575
584
576
585
current_scan.spectral_selection_start = TRY (stream.read_value <u8 >());
0 commit comments