Pictures now parse properly

This commit is contained in:
Serial 2021-05-19 01:00:18 -04:00
parent a6d49fd9ce
commit 0d5724d661
2 changed files with 48 additions and 38 deletions

View file

@ -1,6 +1,6 @@
use crate::{Error, Result}; use crate::{Error, Result};
use byteorder::{LittleEndian, ReadBytesExt}; use byteorder::{BigEndian, ReadBytesExt};
use std::borrow::Cow; use std::borrow::Cow;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::io::{Cursor, Read}; use std::io::{Cursor, Read};
@ -303,42 +303,29 @@ impl Picture {
/// * Id3v2 APIC /// * Id3v2 APIC
/// * Vorbis METADATA_BLOCK_PICTURE /// * Vorbis METADATA_BLOCK_PICTURE
pub fn as_apic_bytes(&self) -> Vec<u8> { pub fn as_apic_bytes(&self) -> Vec<u8> {
let picture_type = self.pic_type.as_u32().to_le_bytes(); let picture_type = self.pic_type.as_u32().to_be_bytes();
let mime_str = String::from(self.mime_type); let mime_str = String::from(self.mime_type);
let mime_len = mime_str.len() as u32; let mime_len = mime_str.len() as u32;
let mut data: Vec<u8> = Vec::new(); let mut data: Vec<u8> = Vec::new();
data.extend(picture_type.iter()); data.extend(picture_type.iter());
data.extend(mime_len.to_le_bytes().iter()); data.extend(mime_len.to_be_bytes().iter());
data.extend(mime_str.as_bytes().iter()); data.extend(mime_str.as_bytes().iter());
if let Some(desc) = self.description.clone() { if let Some(desc) = self.description.clone() {
let desc_str = desc.to_string(); let desc_str = desc.to_string();
let desc_len = desc_str.len() as u32; let desc_len = desc_str.len() as u32;
data.extend(desc_len.to_le_bytes().iter()); data.extend(desc_len.to_be_bytes().iter());
data.extend(desc_str.as_bytes().iter()); data.extend(desc_str.as_bytes().iter());
} }
data.extend(self.data.iter()); let pic_data = &self.data;
let pic_data_len = pic_data.len() as u32;
data data.extend(pic_data_len.to_be_bytes().iter());
} data.extend(pic_data.iter());
/// Convert the `Picture` back to an APEv2 byte vec:
///
/// * APEv2 Cover Art
pub fn as_ape_bytes(&self) -> Vec<u8> {
let mut data: Vec<u8> = Vec::new();
if let Some(desc) = self.description.clone() {
let desc_str = desc.to_string();
data.extend(desc_str.as_bytes().iter());
data.extend([0].iter())
}
data.extend(self.mime_type.as_ape().iter());
data.extend(self.data.iter());
data data
} }
@ -358,10 +345,10 @@ impl Picture {
let mut cursor = Cursor::new(data); let mut cursor = Cursor::new(data);
if let Ok(bytes) = cursor.read_u32::<LittleEndian>() { if let Ok(bytes) = cursor.read_u32::<BigEndian>() {
let picture_type = PictureType::from_u32(bytes); let picture_type = PictureType::from_u32(bytes);
if let Ok(mime_len) = cursor.read_u32::<LittleEndian>() { if let Ok(mime_len) = cursor.read_u32::<BigEndian>() {
let mut buf = vec![0; mime_len as usize]; let mut buf = vec![0; mime_len as usize];
cursor.read_exact(&mut buf)?; cursor.read_exact(&mut buf)?;
@ -369,7 +356,7 @@ impl Picture {
if let Ok(mime_type) = MimeType::try_from(&*mime_type_str) { if let Ok(mime_type) = MimeType::try_from(&*mime_type_str) {
let mut description = None; let mut description = None;
if let Ok(desc_len) = cursor.read_u32::<LittleEndian>() { if let Ok(desc_len) = cursor.read_u32::<BigEndian>() {
if cursor.get_ref().len() if cursor.get_ref().len()
>= (cursor.position() as u32 + desc_len) as usize >= (cursor.position() as u32 + desc_len) as usize
{ {
@ -384,6 +371,7 @@ impl Picture {
} }
} }
if let Ok(_data_len) = cursor.read_u32::<BigEndian>() {
let pos = (cursor.position()) as usize; let pos = (cursor.position()) as usize;
let content = &cursor.into_inner()[pos..]; let content = &cursor.into_inner()[pos..];
@ -397,9 +385,30 @@ impl Picture {
} }
} }
} }
}
Err(Error::InvalidData) Err(Error::InvalidData)
} }
/// Convert the `Picture` back to an APEv2 byte vec:
///
/// * APEv2 Cover Art
pub fn as_ape_bytes(&self) -> Vec<u8> {
const NULL: [u8; 1] = [0];
let mut data: Vec<u8> = Vec::new();
if let Some(desc) = self.description.clone() {
let desc_str = desc.to_string();
data.extend(desc_str.as_bytes().iter());
data.extend(NULL.iter());
}
data.extend(self.mime_type.as_ape().iter());
data.extend(NULL.iter());
data.extend(self.data.iter());
data
}
/// Get a `Picture` from APEv2 bytes: /// Get a `Picture` from APEv2 bytes:
/// ///
/// * APEv2 Cover Art /// * APEv2 Cover Art
@ -460,10 +469,7 @@ impl Picture {
if let Some(mime_type) = mime_type { if let Some(mime_type) = mime_type {
let pos = cursor.position() as usize; let pos = cursor.position() as usize;
let mut data = cursor.into_inner()[pos..].to_vec(); let data = Cow::from(cursor.into_inner()[pos..].to_vec());
data.insert(0, 0);
let data = Cow::from(data);
return Ok(Picture { return Ok(Picture {
pic_type, pic_type,

View file

@ -41,13 +41,17 @@ macro_rules! add_tags {
pic_type: PictureType::CoverFront, pic_type: PictureType::CoverFront,
mime_type: MimeType::Jpeg, mime_type: MimeType::Jpeg,
description: Some(Cow::from("test")), description: Some(Cow::from("test")),
data: Cow::from(vec![0; 11]), data: Cow::from(vec![
51, 50, 51, 50, 51, 50, 51, 50, 49, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
]),
}, },
Picture { Picture {
pic_type: PictureType::CoverBack, pic_type: PictureType::CoverBack,
mime_type: MimeType::Jpeg, mime_type: MimeType::Jpeg,
description: Some(Cow::from("test")), description: Some(Cow::from("test")),
data: Cow::from(vec![0; 11]), data: Cow::from(vec![
51, 50, 51, 50, 51, 50, 51, 50, 49, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
]),
}, },
); );