From 3faf42e2a710ac3f2e075af4090f5f667f07583f Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Thu, 8 Dec 2016 20:52:16 -0500 Subject: [PATCH] Read track number & index as BCD-encoded bytes The track number and track index from the CUEX chunk are BCD-encoded (Binary-Coded Decimal). Reading them as binary led to wrong track numbers starting with track 10. There is doubt whereas the index number is BCD or not, but two-digit indices are seldom seen. --- src/metadata/cuex.rs | 4 ++-- src/metadata/readers.rs | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/metadata/cuex.rs b/src/metadata/cuex.rs index 842017e..accc8c4 100644 --- a/src/metadata/cuex.rs +++ b/src/metadata/cuex.rs @@ -153,8 +153,8 @@ pub fn read_nrg_cuex(fd: &mut File) -> Result { fn read_nrg_cuex_track(fd: &mut File) -> Result { let mut track = NrgCuexTrack::new(); track.mode = try!(read_u8(fd)); - track.track_number = try!(read_u8(fd)); - track.index_number = try!(read_u8(fd)); + track.track_number = try!(read_u8_bcd(fd)); + track.index_number = try!(read_u8_bcd(fd)); track.padding = try!(read_u8(fd)); track.position_sectors = try!(read_u32(fd)) as i32; Ok(track) diff --git a/src/metadata/readers.rs b/src/metadata/readers.rs index 45bc410..b35aef7 100644 --- a/src/metadata/readers.rs +++ b/src/metadata/readers.rs @@ -97,3 +97,19 @@ pub fn read_u8(fd: &mut File) -> Result { try!(fd.read_exact(&mut buf)); Ok(buf[0]) } + + +/// Reads a BCD-encoded byte from `fd`. +/// +/// If the decoded value is more than 99, which is not a valid binary-coded +/// decimal value, the byte read is returned as is, without decoding. +pub fn read_u8_bcd(fd: &mut File) -> Result { + let byte = try!(read_u8(fd)); + let tens = (byte >> 4) * 10; + let units = (byte << 4) >> 4; + let value = tens + units; + if value < 100 { + return Ok(value); + } + Ok(byte) +}