Coverage Report

Created: 2026-10-28 07:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/symphonia/symphonia-format-isomp4/src/atoms/alac.rs
Line
Count
Source
1
// Symphonia
2
// Copyright (c) 2019-2026 The Project Symphonia Developers.
3
//
4
// This Source Code Form is subject to the terms of the Mozilla Public
5
// License, v. 2.0. If a copy of the MPL was not distributed with this
6
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
7
8
use symphonia_core::codecs::audio::well_known::CODEC_ID_ALAC;
9
10
use symphonia_common::apple::audio::alac::MagicCookie;
11
12
use crate::atoms::stsd::AudioSampleEntry;
13
use crate::atoms::{
14
    Atom, AtomHeader, AtomIterator, ReadAtom, Result, decode_error, unsupported_error,
15
};
16
17
#[allow(dead_code)]
18
#[derive(Debug)]
19
pub struct AlacAtom {
20
    /// ALAC extra data (magic cookie).
21
    extra_data: Box<[u8]>,
22
}
23
24
impl Atom for AlacAtom {
25
3.05k
    fn read<B: ReadAtom>(it: &mut AtomIterator<B>, _header: &AtomHeader) -> Result<Self> {
26
3.05k
        let (version, flags) = it.read_extended_header()?;
27
28
3.04k
        if version != 0 {
29
3
            return unsupported_error("isomp4 (alac): unsupported alac version");
30
3.04k
        }
31
32
3.04k
        if flags != 0 {
33
24
            return decode_error("isomp4 (alac): flags not zero");
34
3.02k
        }
35
36
        // The ALAC magic cookie (aka extra data) is either 24 or 48 bytes long.
37
3.02k
        let magic_len = match it.data_left()? {
38
2.94k
            Some(len @ 24) | Some(len @ 48) => len as usize,
39
            Some(_) => {
40
74
                return decode_error("isomp4 (alac): invalid magic cookie length");
41
            }
42
1
            None => return decode_error("isomp4 (alac): unknown magic cookie length"),
43
        };
44
45
        // Read the magic cookie.
46
2.94k
        let extra_data = it.read_boxed_slice_exact(magic_len)?;
47
48
2.93k
        Ok(AlacAtom { extra_data })
49
3.05k
    }
50
}
51
52
impl AlacAtom {
53
2.93k
    pub fn fill_audio_sample_entry(self, entry: &mut AudioSampleEntry) {
54
2.93k
        entry.codec_id = CODEC_ID_ALAC;
55
56
        // Try to parse the magic cookie.
57
2.93k
        if let Ok(cookie) = MagicCookie::read(&self.extra_data) {
58
231
            entry.channels = Some(cookie.channels);
59
231
            entry.sample_rate = f64::from(cookie.sample_rate);
60
2.69k
        }
61
62
2.93k
        entry.extra_data = Some(self.extra_data);
63
2.93k
    }
64
}