Skip to content

Commit f87fa0a

Browse files
committed
Ilst: Create Ilst::is_* methods for flag atoms
1 parent 9eb35ae commit f87fa0a

File tree

2 files changed

+94
-90
lines changed

2 files changed

+94
-90
lines changed

lofty/src/mp4/ilst/constants.rs

Lines changed: 21 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,23 @@
1-
// https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/Metadata/Metadata.html#//apple_ref/doc/uid/TP40000939-CH1-SW35
2-
3-
/// Reserved for use where no type needs to be indicated
4-
pub const RESERVED: u32 = 0;
5-
/// UTF-8 string without any count or NULL terminator
6-
pub const UTF8: u32 = 1;
7-
/// A big-endian UTF-16 string
8-
pub const UTF16: u32 = 2;
9-
/// Deprecated unless it is needed for special Japanese characters
10-
pub const S_JIS: u32 = 3;
11-
/// The UTF-8 variant storage of a string for sorting only
12-
pub const UTF8_SORT: u32 = 4;
13-
/// The UTF-16 variant storage of a string for sorting only
14-
pub const UTF16_SORT: u32 = 5;
15-
/// A JPEG in a JFIF wrapper
16-
pub const JPEG: u32 = 13;
17-
/// A PNG in a PNG wrapper
18-
pub const PNG: u32 = 14;
19-
/// A big-endian signed integer in 1,2,3 or 4 bytes
20-
pub const BE_SIGNED_INTEGER: u32 = 21;
21-
/// A big-endian unsigned integer in 1,2,3 or 4 bytes; size of value determines integer size
22-
pub const BE_UNSIGNED_INTEGER: u32 = 22;
23-
/// A big-endian 32-bit floating point value (IEEE754)
24-
pub const BE_FLOAT32: u32 = 23;
25-
/// A big-endian 64-bit floating point value (IEEE754)
26-
pub const BE_FLOAT64: u32 = 24;
27-
/// Windows bitmap format graphics
28-
pub const BMP: u32 = 27;
29-
/// A QuickTime metadata atom
30-
pub const QUICKTIME_METADATA: u32 = 28;
31-
/// An 8-bit signed integer
32-
pub const SIGNED_8BIT_INTEGER: u32 = 65;
33-
/// A big-endian 16-bit signed integer
34-
pub const BE_16BIT_SIGNED_INTEGER: u32 = 66;
35-
/// A big-endian 32-bit signed integer
36-
pub const BE_32BIT_SIGNED_INTEGER: u32 = 67;
37-
/// A block of data representing a two dimensional (2D) point with 32-bit big-endian floating point x and y coordinates. It has the structure:
38-
///
39-
/// ```c
40-
/// struct {
41-
/// BEFloat32 x;
42-
/// BEFloat32 y;
43-
/// }
44-
/// ```
45-
pub const BE_POINT_F32: u32 = 70;
46-
/// A block of data representing 2D dimensions with 32-bit big-endian floating point width and height. It has the structure:
47-
///
48-
/// ```c
49-
/// struct {
50-
/// BEFloat32 width;
51-
/// BEFloat32 height;
52-
/// }
53-
/// ```
54-
pub const BE_DIMENSIONS_F32: u32 = 71;
55-
/// A block of data representing a 2D rectangle with 32-bit big-endian floating point x and y coordinates and a 32-bit big-endian floating point width and height size. It has the structure:
56-
///
57-
/// ```c
58-
/// struct {
59-
/// BEFloat32 x;
60-
/// BEFloat32 y;
61-
/// BEFloat32 width;
62-
/// BEFloat32 height;
63-
/// }
64-
/// ```
1+
/// Identifiers for flag atoms
652
///
66-
/// or the equivalent structure:
3+
/// Any identifier in here will be treated as having [`AtomData::Bool`] as its data type when parsing.
4+
/// See [`Ilst::set_flag`] for more information.
675
///
68-
/// ```c
69-
/// struct {
70-
/// PointF32 origin;
71-
/// DimensionsF32 size;
72-
/// }
73-
/// ```
74-
pub const BE_RECT_F32: u32 = 72;
75-
/// A big-endian 64-bit signed integer
76-
pub const BE_64BIT_SIGNED_INTEGER: u32 = 74;
77-
/// An 8-bit unsigned integer
78-
pub const UNSIGNED_8BIT_INTEGER: u32 = 75;
79-
/// A big-endian 16-bit unsigned integer
80-
pub const BE_16BIT_UNSIGNED_INTEGER: u32 = 76;
81-
/// A big-endian 32-bit unsigned integer
82-
pub const BE_32BIT_UNSIGNED_INTEGER: u32 = 77;
83-
/// A big-endian 64-bit unsigned integer
84-
pub const BE_64BIT_UNSIGNED_INTEGER: u32 = 78;
85-
/// A block of data representing a 3x3 transformation matrix. It has the structure:
86-
///
87-
/// ```c
88-
/// struct {
89-
/// BEFloat64 matrix[3][3];
90-
/// }
91-
/// ```
92-
pub const AFFINE_TRANSFORM_F64: u32 = 79;
6+
/// [`AtomData::Bool`]: crate::mp4::AtomData::Bool
7+
/// [`Ilst::set_flag`]: crate::mp4::Ilst::set_flag
8+
pub mod flags {
9+
use crate::mp4::AtomIdent;
10+
11+
/// Podcast flag (`pcst`)
12+
pub const PODCAST: AtomIdent<'_> = AtomIdent::Fourcc(*b"pcst");
13+
/// Gapless playback flag (`pgap`)
14+
pub const GAPLESS: AtomIdent<'_> = AtomIdent::Fourcc(*b"pgap");
15+
/// Show work and movement flag (`shwm`)
16+
pub const SHOW_WORK: AtomIdent<'_> = AtomIdent::Fourcc(*b"shwm");
17+
/// HD video flag (`hdvd`)
18+
pub const HD_VIDEO: AtomIdent<'_> = AtomIdent::Fourcc(*b"hdvd");
19+
/// Compilation flag (`cpil`)
20+
pub const COMPILATION: AtomIdent<'_> = AtomIdent::Fourcc(*b"cpil");
21+
}
22+
23+
pub(crate) const WELL_KNOWN_TYPE_SET: u8 = 0;

lofty/src/mp4/ilst/mod.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,32 @@ macro_rules! impl_accessor {
6464
}
6565
}
6666

67+
macro_rules! impl_flag_accessors {
68+
($($name:ident ($ident:ident)),+ $(,)?) => {
69+
$(
70+
paste::paste! {
71+
#[doc = "Whether the `" $ident "` flag atom is set"]
72+
///
73+
/// # Examples
74+
///
75+
/// ```rust
76+
#[doc = "use lofty::mp4::constants::flags::" $name ";"]
77+
/// use lofty::mp4::{AtomIdent, Ilst};
78+
///
79+
/// let mut ilst = Ilst::new();
80+
///
81+
/// // I want to toggle this flag!
82+
#[doc = "ilst.set_flag(" $name ", true);"]
83+
///
84+
#[doc = "assert!(ilst.is_" $name:lower "());"]
85+
pub fn [<is_ $name:lower>](&self) -> bool {
86+
self.get_flag(&constants::flags::$name).unwrap_or(false)
87+
}
88+
}
89+
)+
90+
};
91+
}
92+
6793
/// ## Pictures
6894
///
6995
/// Unlike other formats, ilst does not store a [`PictureType`]. All pictures will have
@@ -349,6 +375,53 @@ impl Ilst {
349375
.retain(|a| !matches!(a.data().next(), Some(AtomData::Picture(_))))
350376
}
351377

378+
/// Sets the value of a flag ([`AtomData::Bool`]) atom
379+
///
380+
/// For identifiers, see [`constants::flags`].
381+
///
382+
/// # Examples
383+
///
384+
/// ```rust
385+
/// use lofty::mp4::constants::flags::COMPILATION;
386+
/// use lofty::mp4::{AtomIdent, Ilst};
387+
///
388+
/// // This file part of a compilation!
389+
/// let mut ilst = Ilst::new();
390+
/// ilst.set_flag(COMPILATION, true);
391+
///
392+
/// assert!(ilst.is_compilation());
393+
/// ```
394+
pub fn set_flag(&mut self, ident: AtomIdent<'_>, value: bool) {
395+
if !value {
396+
// A flag with a value of `false` is equivalent to removing it.
397+
let _ = self.remove(&ident);
398+
return;
399+
}
400+
401+
let data = AtomData::Bool(value);
402+
self.replace_atom(Atom {
403+
ident,
404+
data: AtomDataStorage::Single(data),
405+
});
406+
}
407+
408+
fn get_flag(&self, ident: &AtomIdent<'_>) -> Option<bool> {
409+
self.get(ident)
410+
.and_then(|atom| atom.data().next())
411+
.and_then(|data| match data {
412+
AtomData::Bool(b) => Some(*b),
413+
_ => None,
414+
})
415+
}
416+
417+
impl_flag_accessors!(
418+
PODCAST(pcst),
419+
GAPLESS(pgap),
420+
SHOW_WORK(shwm),
421+
HD_VIDEO(hdvd),
422+
COMPILATION(cpil)
423+
);
424+
352425
/// Returns the parental advisory rating according to the `rtng` atom
353426
pub fn advisory_rating(&self) -> Option<AdvisoryRating> {
354427
self.get(&ADVISORY_RATING)

0 commit comments

Comments
 (0)