Skip to main content

rav1d_safe/
lib.rs

1#![allow(non_upper_case_globals)]
2#![cfg_attr(target_arch = "arm", feature(stdarch_arm_feature_detection))]
3#![cfg_attr(
4    any(target_arch = "riscv32", target_arch = "riscv64"),
5    feature(stdarch_riscv_feature_detection)
6)]
7// Crate-wide forbid(unsafe_code) when neither `asm` nor `c-ffi` is enabled.
8// All unsafe must live in separate crates (rav1d-disjoint-mut, rav1d-align, etc.)
9// or be gated behind cfg(feature = "asm") / cfg(feature = "c-ffi").
10// forbid cannot be overridden by #[allow] — any unsafe in the default build is a hard error.
11#![cfg_attr(
12    not(any(feature = "asm", feature = "c-ffi", feature = "unchecked")),
13    forbid(unsafe_code)
14)]
15#![cfg_attr(any(feature = "asm", feature = "c-ffi"), deny(unsafe_op_in_unsafe_fn))]
16// Clippy lint policy: suppress pervasive C-port patterns at crate level,
17// enable everything else. Each lint has a reason and warning count.
18//
19// Pervasive C-port patterns (too many to fix individually):
20#![allow(clippy::precedence)] // 652: C-style arithmetic
21#![allow(clippy::too_many_arguments)] // 282: C function signatures
22#![allow(clippy::unnecessary_cast)] // 189: generic/bitdepth code
23#![allow(clippy::identity_op)] // 156: readability in transforms
24#![allow(clippy::needless_range_loop)] // 143: C-port loop idiom
25#![allow(clippy::explicit_auto_deref)] // 85: deref style
26#![allow(clippy::erasing_op)] // 53: generic transform constants
27#![allow(clippy::needless_return)] // 24: C-port return style
28#![allow(clippy::nonminimal_bool)] // 23: C-port booleans
29#![allow(clippy::needless_borrow)] // 19: borrow style
30#![allow(clippy::doc_overindented_list_items)] // 16: doc formatting
31#![allow(clippy::zero_prefixed_literal)] // 12: decimal C constants
32#![allow(clippy::collapsible_if)] // 11: nested ifs from C
33#![allow(clippy::needless_late_init)] // 10: C-style init
34//
35// Structural C-port patterns (changing would obscure correspondence):
36#![allow(clippy::upper_case_acronyms)] // 9: AV1 spec names
37#![allow(clippy::type_complexity)] // 4: internal C-port types
38#![allow(clippy::misrefactored_assign_op)] // 4: boundary clamping
39#![allow(clippy::neg_multiply)] // 4: C-style negation
40//
41// Intentional patterns (deny-by-default, false positives here):
42#![allow(clippy::eq_op)] // 2: intentional 2-2
43#![allow(clippy::overly_complex_bool_expr)] // 2: debug gates
44#![allow(clippy::let_underscore_lock)] // 2: lock drop via take()
45//
46// Informational lints not worth acting on:
47#![allow(clippy::module_inception)] // 1: dav1d::dav1d
48#![allow(clippy::large_enum_variant)] // 1: internal enum
49//
50// Newer clippy lints (1.87+) firing on C-port patterns:
51#![allow(clippy::duplicated_attributes)] // new in clippy 1.87+: repeated cfg_attr
52#![allow(clippy::manual_is_multiple_of)] // new in clippy 1.87+: x % n == 0 patterns
53#![allow(clippy::let_and_return)] // new in clippy 1.87+: C-port let-then-return
54#![allow(clippy::unnecessary_map_on_constructor)] // new in clippy 1.87+: Option/Result::map on constructor
55#![allow(clippy::clone_on_copy)] // new in clippy 1.87+: explicit .clone() on Copy types
56#![allow(clippy::option_map_unit_fn)] // new in clippy 1.87+: .map(|x| side_effect)
57#![allow(clippy::unnecessary_lazy_evaluations)] // new in clippy 1.87+: .unwrap_or_else(|| val)
58#![cfg_attr(
59    any(feature = "asm", feature = "c-ffi"),
60    deny(clippy::undocumented_unsafe_blocks)
61)]
62#![cfg_attr(
63    any(feature = "asm", feature = "c-ffi"),
64    deny(clippy::missing_safety_doc)
65)]
66
67#[cfg(not(any(feature = "bitdepth_8", feature = "bitdepth_16")))]
68compile_error!(
69    "No bitdepths enabled. Enable one or more of the following features: `bitdepth_8`, `bitdepth_16`"
70);
71
72pub mod include {
73    pub mod common {
74        pub(crate) mod attributes;
75        pub(crate) mod bitdepth;
76        pub(crate) mod dump;
77        pub(crate) mod intops;
78        pub(crate) mod validate;
79    } // mod common
80    #[cfg_attr(feature = "c-ffi", allow(unsafe_code))]
81    pub mod dav1d {
82        pub mod common;
83        pub mod data;
84        pub mod dav1d;
85        pub mod headers;
86        pub mod picture;
87    } // mod dav1d
88} // mod include
89pub mod src {
90    // === Module Safety Annotations ===
91    // - Modules with zero unsafe use forbid(unsafe_code) internally
92    // - Modules with isolated unsafe items use item-level #[allow(unsafe_code)]
93    // - Modules that need unsafe only for c-ffi use cfg_attr(feature, allow)
94    // - safe_simd sub-modules set their own forbid/deny (no parent blanket allow)
95
96    // Core primitives
97    pub(crate) mod align;
98    #[cfg(feature = "c-ffi")]
99    pub(crate) mod assume;
100    #[cfg_attr(feature = "c-ffi", allow(unsafe_code))]
101    pub(crate) mod c_arc;
102    #[cfg_attr(feature = "c-ffi", allow(unsafe_code))]
103    pub(crate) mod c_box;
104    pub(crate) mod cpu;
105    pub(crate) mod disjoint_mut;
106    mod ffi_safe;
107    mod in_range;
108    pub(super) mod internal;
109    mod intra_edge;
110    #[cfg_attr(not(feature = "c-ffi"), deny(unsafe_code))]
111    #[cfg_attr(feature = "c-ffi", allow(unsafe_code))]
112    pub(crate) mod log;
113    pub(crate) mod pixels;
114    #[cfg(any(feature = "asm", feature = "c-ffi"))]
115    #[allow(unsafe_code)]
116    pub mod send_sync_non_null;
117    mod tables;
118
119    // Data/picture management
120    mod data;
121    #[cfg_attr(not(feature = "c-ffi"), deny(unsafe_code))]
122    #[cfg_attr(feature = "c-ffi", allow(unsafe_code))]
123    mod picture;
124
125    // DSP dispatch modules (contain _erased functions and fn ptr dispatch)
126    mod cdef;
127    mod filmgrain;
128    mod ipred;
129    mod itx;
130    mod lf_mask;
131    mod loopfilter;
132    mod looprestoration;
133    mod mc;
134    mod pal;
135    mod recon;
136    #[cfg_attr(feature = "asm", allow(unsafe_code))]
137    mod refmvs;
138
139    // Entropy coding (inline SIMD, safe on both x86_64 and aarch64 when asm off)
140    #[cfg_attr(feature = "asm", allow(unsafe_code))]
141    mod msac;
142
143    // Safe SIMD implementations (internal, not part of the public API)
144    #[cfg(not(feature = "asm"))]
145    pub(crate) mod safe_simd;
146
147    // Rust core API (rav1d_open, rav1d_send_data, etc.)
148    #[cfg_attr(not(feature = "c-ffi"), deny(unsafe_code))]
149    #[cfg_attr(feature = "c-ffi", allow(unsafe_code))]
150    pub(crate) mod lib;
151
152    // C FFI wrappers (dav1d_* extern "C" functions)
153    #[cfg(feature = "c-ffi")]
154    #[allow(unsafe_code)]
155    pub mod dav1d_api;
156
157    // === Modules WITHOUT unsafe_code (enforced by deny) ===
158    mod cdef_apply;
159    mod cdf;
160    mod const_fn;
161    mod ctx;
162    mod cursor;
163    mod decode;
164    mod dequant_tables;
165    pub(crate) mod enum_map;
166    mod env;
167    pub(crate) mod error;
168    mod extensions;
169    mod fg_apply;
170    mod getbits;
171    mod ipred_prepare;
172    mod iter;
173    mod itx_1d;
174    pub(crate) mod levels;
175    mod lf_apply;
176    mod lr_apply;
177    pub(crate) mod mem;
178    mod obu;
179    pub(crate) mod pic_or_buf;
180    mod qm;
181    pub(crate) mod relaxed_atomic;
182    mod scan;
183    pub(crate) mod strided;
184    mod thread_task;
185    mod warpmv;
186    mod wedge;
187    pub(crate) mod with_offset;
188    pub(crate) mod wrap_fn_ptr;
189
190    #[cfg(test)]
191    mod decode_test;
192
193    // === Managed Safe API ===
194    /// 100% safe Rust API for AV1 decoding
195    ///
196    /// This module provides a fully safe, zero-copy API wrapping rav1d's internal decoder.
197    pub mod managed;
198} // mod src
199
200// Re-export the managed API at the crate root for convenience.
201// Users can write `rav1d_safe::Decoder` instead of `rav1d_safe::src::managed::Decoder`.
202pub use src::managed::{
203    ColorInfo, ColorPrimaries, ColorRange, ContentLightLevel, CpuLevel, DecodeFrameType, Decoder,
204    Error, Frame, InloopFilters, MasteringDisplay, MatrixCoefficients, PixelLayout, PlaneView8,
205    PlaneView16, Planes, Planes8, Planes16, Result, Settings, TransferCharacteristics,
206    enabled_features,
207};