@@ -27,6 +27,7 @@ const ALBUM: AtomIdent<'_> = AtomIdent::Fourcc(*b"\xa9alb");
27
27
const GENRE : AtomIdent < ' _ > = AtomIdent :: Fourcc ( * b"\xa9 gen" ) ;
28
28
const COMMENT : AtomIdent < ' _ > = AtomIdent :: Fourcc ( * b"\xa9 cmt" ) ;
29
29
const ADVISORY_RATING : AtomIdent < ' _ > = AtomIdent :: Fourcc ( * b"rtng" ) ;
30
+ const COVR : AtomIdent < ' _ > = AtomIdent :: Fourcc ( * b"covr" ) ;
30
31
31
32
macro_rules! impl_accessor {
32
33
( $( $name: ident => $const: ident; ) +) => {
@@ -118,6 +119,10 @@ impl Ilst {
118
119
self . atoms . iter ( ) . find ( |a| & a. ident == ident)
119
120
}
120
121
122
+ fn get_mut ( & mut self , ident : & AtomIdent < ' _ > ) -> Option < & mut Atom < ' static > > {
123
+ self . atoms . iter_mut ( ) . find ( |a| & a. ident == ident)
124
+ }
125
+
121
126
/// Inserts an [`Atom`]
122
127
///
123
128
/// # Examples
@@ -138,6 +143,16 @@ impl Ilst {
138
143
/// assert!(title.is_some());
139
144
/// ```
140
145
pub fn insert ( & mut self , atom : Atom < ' _ > ) {
146
+ if atom. ident == COVR && atom. data . is_pictures ( ) {
147
+ for data in atom. data {
148
+ match data {
149
+ AtomData :: Picture ( p) => self . insert_picture ( p) ,
150
+ _ => unreachable ! ( ) ,
151
+ }
152
+ }
153
+ return ;
154
+ }
155
+
141
156
self . atoms . push ( atom. into_owned ( ) ) ;
142
157
}
143
158
@@ -216,31 +231,98 @@ impl Ilst {
216
231
self . atoms . retain ( f)
217
232
}
218
233
219
- /// Returns all pictures
220
- pub fn pictures ( & self ) -> impl Iterator < Item = & Picture > + Clone {
221
- const COVR : AtomIdent < ' _ > = AtomIdent :: Fourcc ( * b"covr" ) ;
222
-
223
- self . atoms . iter ( ) . filter_map ( |a| match a. ident {
224
- COVR => {
225
- if let Some ( AtomData :: Picture ( pic) ) = a. data ( ) . next ( ) {
226
- Some ( pic)
227
- } else {
228
- None
229
- }
230
- } ,
231
- _ => None ,
232
- } )
234
+ /// Returns all pictures, if there are any
235
+ ///
236
+ /// # Examples
237
+ ///
238
+ /// ```rust
239
+ /// use lofty::mp4::Ilst;
240
+ /// use lofty::{MimeType, Picture, PictureType, TagExt};
241
+ ///
242
+ /// let mut ilst = Ilst::new();
243
+ ///
244
+ /// # let png_data = b"foo".to_vec();
245
+ /// // Insert pictures
246
+ /// ilst.insert_picture(Picture::new_unchecked(
247
+ /// PictureType::Other,
248
+ /// MimeType::Png,
249
+ /// None,
250
+ /// png_data,
251
+ /// ));
252
+ ///
253
+ /// # let jpeg_data = b"bar".to_vec();
254
+ /// ilst.insert_picture(Picture::new_unchecked(
255
+ /// PictureType::Other,
256
+ /// MimeType::Jpeg,
257
+ /// None,
258
+ /// jpeg_data,
259
+ /// ));
260
+ ///
261
+ /// assert_eq!(ilst.pictures().unwrap().count(), 2);
262
+ /// ```
263
+ pub fn pictures ( & self ) -> Option < impl Iterator < Item = & Picture > > {
264
+ let Some ( covr) = self . get ( & COVR ) else {
265
+ return None ;
266
+ } ;
267
+
268
+ Some ( covr. data ( ) . filter_map ( |d| {
269
+ if let AtomData :: Picture ( pic) = d {
270
+ Some ( pic)
271
+ } else {
272
+ None
273
+ }
274
+ } ) )
233
275
}
234
276
235
277
/// Inserts a picture
278
+ ///
279
+ /// NOTE: If a `covr` atom exists in the tag, the picture will be appended to it.
280
+ ///
281
+ /// # Examples
282
+ ///
283
+ /// ```rust
284
+ /// use lofty::mp4::Ilst;
285
+ /// use lofty::{MimeType, Picture, PictureType, TagExt};
286
+ ///
287
+ /// let mut ilst = Ilst::new();
288
+ ///
289
+ /// # let png_data = b"foo".to_vec();
290
+ /// // Insert a single picture
291
+ /// ilst.insert_picture(Picture::new_unchecked(
292
+ /// PictureType::Other,
293
+ /// MimeType::Png,
294
+ /// None,
295
+ /// png_data,
296
+ /// ));
297
+ /// assert_eq!(ilst.len(), 1);
298
+ ///
299
+ /// # let jpeg_data = b"bar".to_vec();
300
+ /// // Insert another picture
301
+ /// ilst.insert_picture(Picture::new_unchecked(
302
+ /// PictureType::Other,
303
+ /// MimeType::Jpeg,
304
+ /// None,
305
+ /// jpeg_data,
306
+ /// ));
307
+ ///
308
+ /// // The existing `covr` atom is reused
309
+ /// assert_eq!(ilst.len(), 1);
310
+ /// assert_eq!(ilst.pictures().unwrap().count(), 2);
311
+ /// ```
236
312
pub fn insert_picture ( & mut self , mut picture : Picture ) {
237
313
// This is just for correctness, it doesn't really matter.
238
314
picture. pic_type = PictureType :: Other ;
239
315
240
- self . atoms . push ( Atom {
241
- ident : AtomIdent :: Fourcc ( * b"covr" ) ,
242
- data : AtomDataStorage :: Single ( AtomData :: Picture ( picture) ) ,
243
- } )
316
+ let data = AtomData :: Picture ( picture) ;
317
+ let Some ( existing_covr) = self . get_mut ( & COVR ) else {
318
+ self . atoms . push ( Atom {
319
+ ident : COVR ,
320
+ data : AtomDataStorage :: Single ( data) ,
321
+ } ) ;
322
+ return ;
323
+ } ;
324
+
325
+ existing_covr. push_data ( data) ;
244
326
}
245
327
246
328
/// Removes all pictures
0 commit comments