basis_universal/encoding/
compressor.rs

1use super::*;
2use basis_universal_sys as sys;
3pub use basis_universal_sys::ColorU8;
4
5/// Error codes that can be returned when encoding basis-universal data with a [Compressor]
6#[allow(non_camel_case_types)]
7#[derive(Copy, Clone, Debug, PartialEq)]
8#[repr(i32)]
9pub enum CompressorErrorCode {
10    cECFailedReadingSourceImages =
11        sys::basisu_basis_compressor_error_code_cECFailedReadingSourceImages,
12    cECFailedValidating = sys::basisu_basis_compressor_error_code_cECFailedValidating,
13    cECFailedEncodeUASTC = sys::basisu_basis_compressor_error_code_cECFailedEncodeUASTC,
14    cECFailedFrontEnd = sys::basisu_basis_compressor_error_code_cECFailedFrontEnd,
15    cECFailedFontendExtract = sys::basisu_basis_compressor_error_code_cECFailedFontendExtract,
16    cECFailedBackend = sys::basisu_basis_compressor_error_code_cECFailedBackend,
17    cECFailedCreateBasisFile = sys::basisu_basis_compressor_error_code_cECFailedCreateBasisFile,
18    cECFailedWritingOutput = sys::basisu_basis_compressor_error_code_cECFailedWritingOutput,
19    cECFailedUASTCRDOPostProcess =
20        sys::basisu_basis_compressor_error_code_cECFailedUASTCRDOPostProcess,
21}
22
23impl Into<sys::basisu_basis_compressor_error_code> for CompressorErrorCode {
24    fn into(self) -> sys::basisu_basis_compressor_error_code {
25        self as sys::basisu_basis_compressor_error_code
26    }
27}
28
29impl From<sys::basisu_basis_compressor_error_code> for CompressorErrorCode {
30    fn from(value: sys::basisu_basis_compressor_error_code) -> Self {
31        unsafe { std::mem::transmute(value as u32) }
32    }
33}
34
35/// Used to encode raw image data to basis-universal form
36pub struct Compressor(pub *mut sys::Compressor);
37
38unsafe impl Send for Compressor {}
39
40impl Compressor {
41    /// total_thread_count is passed directly to basisu::job_pool
42    /// total_thread_count is the TOTAL number of job pool threads, including the calling thread! So 2=1 new thread, 3=2 new threads, etc.
43    ///
44    /// Call `encoder_init`
45    pub fn new(total_thread_count: u32) -> Self {
46        encoder_init();
47        unsafe {
48            assert!(total_thread_count > 0);
49            Compressor(sys::compressor_new(total_thread_count as _))
50        }
51    }
52
53    /// Configure the compressor to compress images. `CompressorParams` includes both the image data
54    /// and parameters that affect compression (such as quality or whether mipmaps should be
55    /// generated)
56    ///
57    /// # Safety
58    ///
59    /// Passing invalid parameters may cause undefined behavior. (The underlying C++ library does
60    /// not thoroughly validate parameters)
61    pub unsafe fn init(
62        &mut self,
63        params: &CompressorParams,
64    ) -> bool {
65        sys::compressor_init(self.0, params.0)
66    }
67
68    /// Encodes the images as configured when calling `init()`
69    ///
70    /// # Safety
71    ///
72    /// Compressing with invalid parameters may cause undefined behavior. (The underlying C++
73    /// library does not thoroughly validate parameters)
74    pub unsafe fn process(&mut self) -> Result<(), CompressorErrorCode> {
75        let result = sys::compressor_process(self.0);
76        if result == sys::basisu_basis_compressor_error_code_cECSuccess {
77            Ok(())
78        } else {
79            Err(result.into())
80        }
81    }
82
83    /// Access the compressed data. May be empty if `process()` was not yet called
84    pub fn basis_file(&self) -> &[u8] {
85        unsafe {
86            let result = sys::compressor_get_output_basis_file(self.0);
87            std::slice::from_raw_parts(result.pData, result.length as usize)
88        }
89    }
90
91    /// Return the size of the encoded basis-universal data
92    pub fn basis_file_size(&self) -> u32 {
93        unsafe { sys::compressor_get_basis_file_size(self.0) }
94    }
95
96    /// Returns the number of bits required per texel
97    pub fn bits_per_texel(&self) -> f64 {
98        unsafe { sys::compressor_get_basis_bits_per_texel(self.0) }
99    }
100
101    /// Returns if any source image has alpha
102    pub fn any_source_image_has_alpha(&self) -> bool {
103        unsafe { sys::compressor_get_any_source_image_has_alpha(self.0) }
104    }
105}
106
107impl Default for Compressor {
108    fn default() -> Self {
109        Compressor::new(1)
110    }
111}
112
113impl Drop for Compressor {
114    fn drop(&mut self) {
115        unsafe {
116            sys::compressor_delete(self.0);
117        }
118    }
119}