1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//! Core parsing engine for [revelo](https://github.com/vbasky/revelo).
//!
//! Transliterates MediaInfoLib's `File__Analyze` infrastructure — the
//! cursor-based byte reader every parser uses (`Get_B*`, `Get_L*`,
//! `Peek_*`, `Skip_*`, bitstream mode) plus the element trace tree, typed
//! stream collection, runtime config, and event dispatch — while also
//! exposing ExifTool-style stream kinds (`Exif`, `Iptc`, `Xmp`, `Icc`,
//! `C2pa`, `MakerNotes`) for camera-maker-note depth.
//!
//! All read methods return native Rust types (`u8`–`u128`, `f32`, `f64`)
//! rather than out-parameters or C-style aliases. Truncated reads return
//! `0` / empty slices and set a `truncated()` flag rather than panicking.
//!
//! # Key public types
//!
//! | Type | Role |
//! |------|------|
//! | [`FileAnalyze`] | Cursor over a `&[u8]` buffer; received by every parser |
//! | [`MediaFile`] | Public type alias for `FileAnalyze` |
//! | [`StreamCollection`] | All parsed fields, keyed by `(StreamKind, position)` |
//! | [`Stream`] | A single stream's fields in insertion order plus an `<extra>` bucket |
//! | [`StreamKind`] | Discriminant: `General`…`Menu` (MediaInfo-compatible 0–6) + `Exif`…`MakerNotes` (7–12) |
//! | [`ElementTree`] / [`ElementNode`] | Stack-based trace tree (mirrors MediaInfoLib `--trace` output) |
//! | [`Reader`] | Fluent `Option`-returning wrapper over `FileAnalyze` |
//! | `MediaConfig` | Demux level, trace verbosity, parse speed, multi-file options |
//!
//! # Writing a parser
//!
//! ```no_run
//! use revelo_core::{FileAnalyze, StreamKind};
//!
//! fn my_parser(fa: &mut FileAnalyze) -> bool {
//! // Non-advancing magic check
//! if !fa.peek_magic(b"RIFF") {
//! return false;
//! }
//! let _chunk_size = fa.get_b4("ChunkSize");
//! let _form_tag = fa.get_c4("FormTag");
//!
//! let pos = fa.stream_prepare(StreamKind::General);
//! fa.set_field(StreamKind::General, pos, "Format", "MyFormat");
//! true
//! }
//! ```
//!
//! Or via the higher-level [`Reader`] API (`None` signals truncation instead
//! of falling back to 0):
//!
//! ```no_run
//! use revelo_core::{FileAnalyze, Reader, StreamKind};
//!
//! fn my_parser(fa: &mut FileAnalyze) -> bool {
//! let mut r = Reader::wrap(fa);
//! let Some(_size) = r.be_u32("Size") else { return false; };
//! let pos = r.stream_prepare(StreamKind::Audio);
//! r.set_field(StreamKind::Audio, pos, "BitDepth", "24");
//! true
//! }
//! ```
//!
//! # `#![deny(unsafe_code)]`
//!
//! The entire crate is enforced `unsafe`-free.
pub use ;
pub use FileAnalyze;
/// Ergonomic alias for [`FileAnalyze`]. Both names refer to the same type.
pub type MediaFile<'a> = ;
pub use ;
pub use Reader;
pub use ;
/// Container-level reference file tracker.
/// Round-to-nearest duration in milliseconds from sample count and sample rate.
///
/// Uses `(samples * 1000 + rate / 2) / rate` to match mediainfo's rounding
/// rather than truncation via `(samples * 1000) / rate`.