Skip to main content

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}