Skip to content

Commit 166d01b

Browse files
committed
Fix compatibility of Lossless code when not used
Ensures that Spectral Selection start is only parsed as predictor when we are actually in Lossless coding mode. Otherwise, images where a scan has a start above 8 (in particular, progressive images) would fail to decode despite not actually utilizing the predictor.
1 parent 9ee9ec7 commit 166d01b

File tree

1 file changed

+20
-13
lines changed

1 file changed

+20
-13
lines changed

src/parser.rs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -388,29 +388,22 @@ pub fn parse_sos<R: Read>(reader: &mut R, frame: &FrameInfo) -> Result<ScanInfo>
388388
return Err(Error::Format("scan with more than one component and more than 10 blocks per MCU".to_owned()));
389389
}
390390

391+
// Also utilized as 'Predictor' in lossless coding, as MEAN in JPEG-LS etc.
391392
let spectral_selection_start = read_u8(reader)?;
393+
// Also utilized as ILV parameter in JPEG-LS.
392394
let mut spectral_selection_end = read_u8(reader)?;
393395

394396
let byte = read_u8(reader)?;
395397
let successive_approximation_high = byte >> 4;
396398
let successive_approximation_low = byte & 0x0f;
397399

398-
let predictor_selection = match spectral_selection_start {
399-
0 => Predictor::NoPrediction,
400-
1 => Predictor::Ra,
401-
2 => Predictor::Rb,
402-
3 => Predictor::Rc,
403-
4 => Predictor::RaRbRc1,
404-
5 => Predictor::RaRbRc2,
405-
6 => Predictor::RaRbRc3,
406-
7 => Predictor::RaRb,
407-
_ => {
408-
return Err(Error::Format(format!("invalid predictor selection value: {}", spectral_selection_start)));
409-
}
410-
};
400+
// The Differential Pulse-Mode prediction used (similar to png). Only utilized in Lossless
401+
// coding. Don't confuse with the JPEG-LS parameter coded using the same scan info portion.
402+
let predictor_selection;
411403
let point_transform = successive_approximation_low;
412404

413405
if frame.coding_process == CodingProcess::DctProgressive {
406+
predictor_selection = Predictor::NoPrediction;
414407
if spectral_selection_end > 63 || spectral_selection_start > spectral_selection_end ||
415408
(spectral_selection_start == 0 && spectral_selection_end != 0) {
416409
return Err(Error::Format(format!("invalid spectral selection parameters: ss={}, se={}", spectral_selection_start, spectral_selection_end)));
@@ -437,8 +430,22 @@ pub fn parse_sos<R: Read>(reader: &mut R, frame: &FrameInfo) -> Result<ScanInfo>
437430
if successive_approximation_high != 0 {
438431
return Err(Error::Format("successive approximation high shall be zero in lossless scan".to_owned()));
439432
}
433+
predictor_selection = match spectral_selection_start {
434+
0 => Predictor::NoPrediction,
435+
1 => Predictor::Ra,
436+
2 => Predictor::Rb,
437+
3 => Predictor::Rc,
438+
4 => Predictor::RaRbRc1,
439+
5 => Predictor::RaRbRc2,
440+
6 => Predictor::RaRbRc3,
441+
7 => Predictor::RaRb,
442+
_ => {
443+
return Err(Error::Format(format!("invalid predictor selection value: {}", spectral_selection_start)));
444+
},
445+
};
440446
}
441447
else {
448+
predictor_selection = Predictor::NoPrediction;
442449
if spectral_selection_end == 0 {
443450
spectral_selection_end = 63;
444451
}

0 commit comments

Comments
 (0)