vyre_wgpu/engine/decode/codec/decoder.rs
1//! Public GPU decode entry points.
2
3use crate::engine::decode::{
4 dispatch::gpu, flatten_regions, recursive_decode, DecodeFormat, DecodeRules, DecodedRegion,
5};
6use vyre::{Error, Result};
7
8/// GPU-backed decoder using vyre's cached runtime device.
9///
10/// This struct is `#[non_exhaustive]` to allow adding new internal state
11/// (like shader caches or command buffers) without breaking consumers.
12///
13/// # Examples
14///
15/// ```
16/// use vyre_wgpu::engine::decode::GpuDecoder;
17///
18/// // Requires a GPU device to succeed.
19/// let _ = GpuDecoder::new();
20/// ```
21#[derive(Debug, Clone, Copy, Default)]
22#[non_exhaustive]
23pub struct GpuDecoder;
24
25impl GpuDecoder {
26 /// Create a decoder backed by `vyre::runtime::cached_device()`.
27 ///
28 /// # Errors
29 ///
30 /// Returns an error if the GPU device cannot be initialized or if the
31 /// hardware is incompatible with the decode shaders.
32 pub fn new() -> Result<Self> {
33 Self::try_new()
34 }
35
36 /// Try to initialize the shared GPU device.
37 ///
38 /// # Errors
39 ///
40 /// Returns `Error::Gpu` if the GPU device cannot be initialized.
41 pub fn try_new() -> Result<Self> {
42 crate::runtime::cached_device()?;
43 Ok(Self)
44 }
45
46 /// Decode all supported encodings recursively.
47 ///
48 /// # Errors
49 ///
50 /// Returns `Error::Decode` if the GPU decode dispatch or recursive frontier management fails.
51 /// Returns `Error::Gpu` if the GPU device cannot be initialized or a buffer operation fails.
52 pub fn decode_recursive(&self, file_bytes: &[u8]) -> Result<Vec<DecodedRegion>> {
53 self.decode_recursive_with_rules(file_bytes, &DecodeRules::default())
54 }
55
56 /// Decode recursively using caller-provided rules.
57 ///
58 /// # Errors
59 ///
60 /// Returns `Error::Decode` if `max_passes` is zero or the GPU decode dispatch fails.
61 /// Returns `Error::Gpu` if the GPU device cannot be initialized or a buffer operation fails.
62 pub fn decode_recursive_with_rules(
63 &self,
64 file_bytes: &[u8],
65 rules: &DecodeRules,
66 ) -> Result<Vec<DecodedRegion>> {
67 decode_recursive_gpu(file_bytes, rules)
68 }
69}
70
71/// Decode a byte buffer as one format and concatenate decoded regions.
72///
73/// # Errors
74///
75/// Returns `Error::DecodeConfig` if the default rules are invalid.
76/// Returns `Error::Decode` if the GPU decode dispatch fails.
77/// Returns `Error::Gpu` if the GPU device cannot be initialized or a buffer operation fails.
78///
79/// # Examples
80///
81/// ```
82/// use vyre_wgpu::engine::decode::{decode_bytes, DecodeFormat};
83///
84/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
85/// let input = b"SGVsbG8=";
86/// let decoded = decode_bytes(input, DecodeFormat::Base64)?;
87/// assert_eq!(decoded, b"Hello");
88/// # Ok(())
89/// # }
90/// ```
91pub fn decode_bytes(input: &[u8], format: DecodeFormat) -> Result<Vec<u8>> {
92 decode_regions(input, format, &DecodeRules::default()).map(flatten_regions)
93}
94
95/// Decode base64 regions and concatenate their decoded bytes.
96///
97/// # Errors
98///
99/// Returns `Error::DecodeConfig` if the default rules are invalid.
100/// Returns `Error::Decode` if the GPU decode dispatch fails.
101/// Returns `Error::Gpu` if the GPU device cannot be initialized or a buffer operation fails.
102pub fn decode_base64(input: &[u8]) -> Result<Vec<u8>> {
103 decode_bytes(input, DecodeFormat::Base64)
104}
105
106/// Decode hex regions and concatenate their decoded bytes.
107///
108/// # Errors
109///
110/// Returns `Error::DecodeConfig` if the default rules are invalid.
111/// Returns `Error::Decode` if the GPU decode dispatch fails.
112/// Returns `Error::Gpu` if the GPU device cannot be initialized or a buffer operation fails.
113pub fn decode_hex(input: &[u8]) -> Result<Vec<u8>> {
114 decode_bytes(input, DecodeFormat::Hex)
115}
116
117/// Decode URL percent-encoded regions and concatenate their decoded bytes.
118///
119/// # Errors
120///
121/// Returns `Error::DecodeConfig` if the default rules are invalid.
122/// Returns `Error::Decode` if the GPU decode dispatch fails.
123/// Returns `Error::Gpu` if the GPU device cannot be initialized or a buffer operation fails.
124pub fn decode_url(input: &[u8]) -> Result<Vec<u8>> {
125 decode_bytes(input, DecodeFormat::Url)
126}
127
128/// Decode unicode escape regions and concatenate their decoded bytes.
129///
130/// # Errors
131///
132/// Returns `Error::DecodeConfig` if the default rules are invalid.
133/// Returns `Error::Decode` if the GPU decode dispatch fails.
134/// Returns `Error::Gpu` if the GPU device cannot be initialized or a buffer operation fails.
135pub fn decode_unicode(input: &[u8]) -> Result<Vec<u8>> {
136 decode_bytes(input, DecodeFormat::Unicode)
137}
138
139/// Decode bytes recursively on the GPU.
140///
141/// # Errors
142///
143/// Returns `Error::DecodeConfig` if the default rules are invalid.
144/// Returns `Error::Gpu` if the GPU device cannot be initialized.
145/// Returns `Error::Decode` if the GPU decode dispatch or recursive frontier management fails.
146pub fn decode_file(file_bytes: &[u8]) -> Result<Vec<DecodedRegion>> {
147 decode_file_with_rules(file_bytes, &DecodeRules::default())
148}
149
150/// Decode bytes recursively using caller-provided rules on the GPU.
151///
152/// # Errors
153///
154/// Returns `Error::DecodeConfig` if the provided rules are invalid.
155/// Returns `Error::Gpu` if the GPU device cannot be initialized.
156/// Returns `Error::Decode` if the GPU decode dispatch or recursive frontier management fails.
157pub fn decode_file_with_rules(
158 file_bytes: &[u8],
159 rules: &DecodeRules,
160) -> Result<Vec<DecodedRegion>> {
161 rules.validate().map_err(|error| Error::DecodeConfig {
162 message: error.to_string(),
163 })?;
164 GpuDecoder::try_new()?.decode_recursive_with_rules(file_bytes, rules)
165}
166
167/// Decode all regions of `format` using the GPU decoder.
168///
169/// # Errors
170///
171/// Returns `Error::DecodeConfig` if the provided rules are invalid.
172/// Returns `Error::Decode` if the GPU decode dispatch fails.
173/// Returns `Error::Gpu` if the GPU device cannot be initialized or a buffer operation fails.
174pub fn decode_regions(
175 input: &[u8],
176 format: DecodeFormat,
177 rules: &DecodeRules,
178) -> Result<Vec<DecodedRegion>> {
179 rules.validate().map_err(|error| Error::DecodeConfig {
180 message: error.to_string(),
181 })?;
182 gpu::dispatch_decode(format, input, rules, None)
183}
184
185/// `decode_recursive_gpu` function.
186pub fn decode_recursive_gpu(file_bytes: &[u8], rules: &DecodeRules) -> Result<Vec<DecodedRegion>> {
187 recursive_decode(file_bytes, rules, |format, input, rules| {
188 gpu::dispatch_decode(format, input, rules, None)
189 })
190}