diff --git a/.gitignore b/.gitignore index 7d3ee6e..39789c0 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,7 @@ bin/act *.png .idea/ +models/ +images/ + +.DS_Store \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 5441bc0..cd25fea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,9 @@ [workspace] members = ["sys"] -resolver = "2" [workspace.package] -version = "0.1.6" -edition = "2021" +version = "0.1.8" +edition = "2024" license = "MIT" repository = "https://github.com/newfla/diffusion-rs" keywords = ["ai", "stable-diffusion", "flux"] @@ -19,14 +18,13 @@ keywords.workspace = true description = "High level API for stable-diffusion.cpp" documentation = "https://docs.rs/diffusion-rs" - [dependencies] derive_builder = "0.20.2" -diffusion-rs-sys = { path = "sys", version = "0.1.6" } -hf-hub = {version = "0.4.0", default-features = false, features = ["ureq"]} -libc = "0.2.161" +diffusion-rs-sys = { path = "sys", version = "0.1.8" } +image = "0.25.6" +libc = "0.2.171" num_cpus = "1.16.0" -thiserror = "2.0.3" +thiserror = "2.0.12" [features] cuda = ["diffusion-rs-sys/cuda"] @@ -34,4 +32,3 @@ hipblas = ["diffusion-rs-sys/hipblas"] metal = ["diffusion-rs-sys/metal"] vulkan = ["diffusion-rs-sys/vulkan"] sycl = ["diffusion-rs-sys/sycl"] -flashattn = ["diffusion-rs-sys/flashattn"] diff --git a/README.md b/README.md index e066cd7..4bcc10a 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,12 @@ # diffusion-rs + [![Latest version](https://img.shields.io/crates/v/diffusion-rs.svg)](https://crates.io/crates/diffusion-rs) [![Documentation](https://docs.rs/diffusion-rs/badge.svg)](https://docs.rs/diffusion-rs) Rust bindings to ## Features Matrix + | | Windows | Mac | Linux | | --- | :---: | :---: | :---: | |vulkan| ✅️ | ⛓️‍💥 | ✅️ | @@ -17,7 +19,8 @@ Rust bindings to ⛓️‍💥 : Issues when linking libraries -## Usage +## Usage + ``` rust no_run use diffusion_rs::{api::txt2img, preset::{Preset,PresetBuilder}}; let config = PresetBuilder::default() @@ -31,16 +34,17 @@ txt2img(config).unwrap(); ## Troubleshooting * Something other than Windows/Linux isn't working! - * I don't have a way to test these platforms, so I can't really help you. + * I don't have a way to test these platforms, so I can't really help you. * I get a panic during binding generation build! - * You can attempt to fix it yourself, or you can set the `DIFFUSION_SKIP_BINDINGS` environment variable. + * You can attempt to fix it yourself, or you can set the `DIFFUSION_SKIP_BINDINGS` environment variable. This skips attempting to build the bindings whatsoever and copies the existing ones. They may be out of date, but it's better than nothing. - * `DIFFUSION_SKIP_BINDINGS=1 cargo build` - * If you can fix the issue, please open a PR! + * `DIFFUSION_SKIP_BINDINGS=1 cargo build` + * If you can fix the issue, please open a PR! ## Roadmap + 1. ~~Ensure that the underline cpp library compiles on supported platforms~~ 2. ~~Build an easy to use library with model presets~~ 3. ~~Automatic library publishing on crates.io by gh actions~~ -4. _Maybe_ prebuilt CLI app binaries \ No newline at end of file +4. _Maybe_ prebuilt CLI app binaries diff --git a/src/api.rs b/src/api.rs index 1dab93d..8dd47f6 100644 --- a/src/api.rs +++ b/src/api.rs @@ -1,567 +1,173 @@ -use std::ffi::c_char; -use std::ffi::c_void; -use std::ffi::CString; -use std::path::Path; -use std::path::PathBuf; +use std::ffi::{CString, c_void}; +use std::mem::ManuallyDrop; use std::ptr::null; use std::slice; -use derive_builder::Builder; -use diffusion_rs_sys::free_upscaler_ctx; -use diffusion_rs_sys::new_upscaler_ctx; +use crate::model_config::ModelConfig; +use crate::txt2img_config::Txt2ImgConfig; +use crate::types::{DiffusionError, LogCallback, ProgressCallback, SdLogLevel}; +use crate::utils::{convert_image, pathbuf_to_c_char}; + use diffusion_rs_sys::sd_image_t; -use diffusion_rs_sys::upscaler_ctx_t; +use image::RgbImage; use libc::free; -use thiserror::Error; - -use diffusion_rs_sys::free_sd_ctx; -use diffusion_rs_sys::new_sd_ctx; -use diffusion_rs_sys::sd_ctx_t; -use diffusion_rs_sys::stbi_write_png_custom; - -/// Specify the range function -pub use diffusion_rs_sys::rng_type_t as RngFunction; - -/// Sampling methods -pub use diffusion_rs_sys::sample_method_t as SampleMethod; -/// Denoiser sigma schedule -pub use diffusion_rs_sys::schedule_t as Schedule; +#[derive(Debug)] +pub struct ModelCtx { + /// The underlying C context + ctx: *mut diffusion_rs_sys::sd_ctx_t, -/// Weight type -pub use diffusion_rs_sys::sd_type_t as WeightType; - -#[non_exhaustive] -#[derive(Error, Debug)] -/// Error that can occurs while forwarding models -pub enum DiffusionError { - #[error("The underling stablediffusion.cpp function returned NULL")] - Forward, - #[error("The underling stbi_write_image function returned 0 while saving image {0}/{1})")] - StoreImages(usize, i32), - #[error("The underling upsclaer model returned a NULL image")] - Upscaler, -} - -#[repr(i32)] -#[non_exhaustive] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -/// Ignore the lower X layers of CLIP network -pub enum ClipSkip { - /// Will be [ClipSkip::None] for SD1.x, [ClipSkip::OneLayer] for SD2.x - #[default] - Unspecified = 0, - None = 1, - OneLayer = 2, + /// We keep the config around in case we need to refer to it + pub config: ModelConfig, } -#[derive(Builder, Debug, Clone)] -#[builder(setter(into, strip_option), build_fn(validate = "Self::validate"))] -/// Config struct common to all diffusion methods -pub struct Config { - /// Number of threads to use during computation (default: 0). - /// If n_ threads <= 0, then threads will be set to the number of CPU physical cores. - #[builder(default = "num_cpus::get_physical() as i32", setter(custom))] - n_threads: i32, - - /// Path to full model - #[builder(default = "Default::default()")] - model: CLibPath, - - /// Path to the standalone diffusion model - #[builder(default = "Default::default()")] - diffusion_model: CLibPath, - - /// path to the clip-l text encoder - #[builder(default = "Default::default()")] - clip_l: CLibPath, - - /// path to the clip-g text encoder - #[builder(default = "Default::default()")] - clip_g: CLibPath, - - /// Path to the t5xxl text encoder - #[builder(default = "Default::default()")] - t5xxl: CLibPath, - - /// Path to vae - #[builder(default = "Default::default()")] - vae: CLibPath, - - /// Path to taesd. Using Tiny AutoEncoder for fast decoding (low quality) - #[builder(default = "Default::default()")] - taesd: CLibPath, - - /// Path to control net model - #[builder(default = "Default::default()")] - control_net: CLibPath, - - /// Path to embeddings - #[builder(default = "Default::default()")] - embeddings: CLibPath, - - /// Path to PHOTOMAKER stacked id embeddings - #[builder(default = "Default::default()")] - stacked_id_embd: CLibPath, - - /// Path to PHOTOMAKER input id images dir - #[builder(default = "Default::default()")] - input_id_images: CLibPath, - - /// Normalize PHOTOMAKER input id images - #[builder(default = "false")] - normalize_input: bool, - - /// Path to esrgan model. Upscale images after generate, just RealESRGAN_x4plus_anime_6B supported by now - #[builder(default = "Default::default()")] - upscale_model: Option, - - /// Run the ESRGAN upscaler this many times (default 1) - #[builder(default = "0")] - upscale_repeats: i32, - - /// Weight type. If not specified, the default is the type of the weight file - #[builder(default = "WeightType::SD_TYPE_COUNT")] - weight_type: WeightType, - - /// Lora model directory - #[builder(default = "Default::default()", setter(custom))] - lora_model: CLibPath, - - /// Path to the input image, required by img2img - #[builder(default = "Default::default()")] - init_img: CLibPath, - - /// Path to image condition, control net - #[builder(default = "Default::default()")] - control_image: CLibPath, - - /// Path to write result image to (default: ./output.png) - #[builder(default = "PathBuf::from(\"./output.png\")")] - output: PathBuf, - - /// The prompt to render - prompt: String, - - /// The negative prompt (default: "") - #[builder(default = "\"\".into()")] - negative_prompt: CLibString, - - /// Unconditional guidance scale (default: 7.0) - #[builder(default = "7.0")] - cfg_scale: f32, - - /// Guidance (default: 3.5) - #[builder(default = "3.5")] - guidance: f32, - - /// Strength for noising/unnoising (default: 0.75) - #[builder(default = "0.75")] - strength: f32, - - /// Strength for keeping input identity (default: 20%) - #[builder(default = "20.0")] - style_ratio: f32, - - /// Strength to apply Control Net (default: 0.9) - /// 1.0 corresponds to full destruction of information in init - #[builder(default = "0.9")] - control_strength: f32, - - /// Image height, in pixel space (default: 512) - #[builder(default = "512")] - height: i32, - - /// Image width, in pixel space (default: 512) - #[builder(default = "512")] - width: i32, - - /// Sampling-method (default: EULER_A) - #[builder(default = "SampleMethod::EULER_A")] - sampling_method: SampleMethod, - - /// Number of sample steps (default: 20) - #[builder(default = "20")] - steps: i32, - - /// RNG (default: CUDA) - #[builder(default = "RngFunction::CUDA_RNG")] - rng: RngFunction, - - /// RNG seed (default: 42, use random seed for < 0) - #[builder(default = "42")] - seed: i64, - - /// Number of images to generate (default: 1) - #[builder(default = "1")] - batch_count: i32, - - /// Denoiser sigma schedule (default: DEFAULT) - #[builder(default = "Schedule::DEFAULT")] - schedule: Schedule, - - /// Ignore last layers of CLIP network; 1 ignores none, 2 ignores one layer (default: -1) - /// <= 0 represents unspecified, will be 1 for SD1.x, 2 for SD2.x - #[builder(default = "ClipSkip::Unspecified")] - clip_skip: ClipSkip, - - /// Process vae in tiles to reduce memory usage (default: false) - #[builder(default = "false")] - vae_tiling: bool, - - /// Keep vae in cpu (for low vram) (default: false) - #[builder(default = "false")] - vae_on_cpu: bool, - - /// keep clip in cpu (for low vram) (default: false) - #[builder(default = "false")] - clip_on_cpu: bool, - - /// Keep controlnet in cpu (for low vram) (default: false) - #[builder(default = "false")] - control_net_cpu: bool, - - /// Apply canny preprocessor (edge detection) (default: false) - #[builder(default = "false")] - canny: bool, - - /// Suffix that needs to be added to prompt (e.g. lora model) - #[builder(default = "None", private)] - prompt_suffix: Option, - - /// Use flash attention in the diffusion model (for low vram). - /// Might lower quality, since it implies converting k and v to f16. - /// This might crash if it is not supported by the backend. - #[builder(default = "false")] - flash_attenuation: bool, - - /// skip layer guidance (SLG) scale, only for DiT models: (default: 0) - /// 0 means disabled, a value of 2.5 is nice for sd3.5 medium - #[builder(default = "0.")] - slg_scale: f32, - - /// Layers to skip for SLG steps: (default: [7,8,9]) - #[builder(default = "vec![7, 8, 9]")] - skip_layer: Vec, - - /// SLG enabling point: (default: 0.01) - #[builder(default = "0.01")] - skip_layer_start: f32, - - /// SLG disabling point: (default: 0.2) - #[builder(default = "0.2")] - skip_layer_end: f32, -} - -impl ConfigBuilder { - pub fn lora_model(&mut self, lora_model: &Path) -> &mut Self { - let folder = lora_model.parent().unwrap(); - let file_name = lora_model.file_stem().unwrap().to_str().unwrap().to_owned(); - self.prompt_suffix(format!("")); - self.lora_model = Some(folder.into()); - self - } - - pub fn n_threads(&mut self, value: i32) -> &mut Self { - self.n_threads = if value > 0 { - Some(value) - } else { - Some(num_cpus::get_physical() as i32) - }; - self - } - - fn validate(&self) -> Result<(), ConfigBuilderError> { - self.validate_model()?; - self.validate_output_dir() - } - - fn validate_model(&self) -> Result<(), ConfigBuilderError> { - self.model - .as_ref() - .or(self.diffusion_model.as_ref()) - .map(|_| ()) - .ok_or(ConfigBuilderError::UninitializedField( - "Model OR DiffusionModel must be valorized", - )) - } - - fn validate_output_dir(&self) -> Result<(), ConfigBuilderError> { - let is_dir = self.output.as_ref().is_some_and(|val| val.is_dir()); - let multiple_items = self.batch_count.as_ref().is_some_and(|val| *val > 1); - if is_dir == multiple_items { - Ok(()) - } else { - Err(ConfigBuilderError::ValidationError( - "When batch_count > 0, ouput should point to folder and viceversa".to_owned(), - )) - } - } -} - -impl Config { - unsafe fn build_sd_ctx(&self, vae_decode_only: bool) -> *mut sd_ctx_t { - new_sd_ctx( - self.model.as_ptr(), - self.clip_l.as_ptr(), - self.clip_g.as_ptr(), - self.t5xxl.as_ptr(), - self.diffusion_model.as_ptr(), - self.vae.as_ptr(), - self.taesd.as_ptr(), - self.control_net.as_ptr(), - self.lora_model.as_ptr(), - self.embeddings.as_ptr(), - self.stacked_id_embd.as_ptr(), - vae_decode_only, - self.vae_tiling, - true, - self.n_threads, - self.weight_type, - self.rng, - self.schedule, - self.clip_on_cpu, - self.control_net_cpu, - self.vae_on_cpu, - self.flash_attenuation, - ) - } - - unsafe fn upscaler_ctx(&self) -> Option<*mut upscaler_ctx_t> { - if self.upscale_model.is_none() || self.upscale_repeats == 0 { - None - } else { - let upscaler = new_upscaler_ctx( - self.upscale_model.as_ref().unwrap().as_ptr(), - self.n_threads, +unsafe impl Send for ModelCtx {} +// unsafe impl Sync for ModelCtx {} + +impl ModelCtx { + pub fn new(config: &ModelConfig) -> Result { + let ctx = unsafe { + let ptr = diffusion_rs_sys::new_sd_ctx( + pathbuf_to_c_char(&config.model).as_ptr(), + pathbuf_to_c_char(&config.clip_l).as_ptr(), + pathbuf_to_c_char(&config.clip_g).as_ptr(), + pathbuf_to_c_char(&config.t5xxl).as_ptr(), + pathbuf_to_c_char(&config.diffusion_model).as_ptr(), + pathbuf_to_c_char(&config.vae).as_ptr(), + pathbuf_to_c_char(&config.taesd).as_ptr(), + pathbuf_to_c_char(&config.control_net).as_ptr(), + pathbuf_to_c_char(&config.lora_model_dir).as_ptr(), + pathbuf_to_c_char(&config.embeddings_dir).as_ptr(), + pathbuf_to_c_char(&config.stacked_id_embd_dir).as_ptr(), + config.vae_decode_only, + config.vae_tiling, + config.free_params_immediately, + config.n_threads, + config.weight_type, + config.rng_type, + config.schedule, + config.keep_clip_on_cpu, + config.keep_control_net_cpu, + config.keep_vae_on_cpu, + config.flash_attention, ); - Some(upscaler) - } - } -} - -#[derive(Debug, Clone, Default)] -struct CLibString(CString); - -impl CLibString { - fn as_ptr(&self) -> *const c_char { - self.0.as_ptr() - } -} - -impl From<&str> for CLibString { - fn from(value: &str) -> Self { - Self(CString::new(value).unwrap()) - } -} - -impl From for CLibString { - fn from(value: String) -> Self { - Self(CString::new(value).unwrap()) - } -} - -#[derive(Debug, Clone, Default)] -struct CLibPath(CString); - -impl CLibPath { - fn as_ptr(&self) -> *const c_char { - self.0.as_ptr() - } -} + if ptr.is_null() { + return Err(DiffusionError::NewContextFailure); + } else { + ptr + } + }; -impl From for CLibPath { - fn from(value: PathBuf) -> Self { - Self(CString::new(value.to_str().unwrap_or_default()).unwrap()) + Ok(Self { + ctx, + config: config.clone(), + }) } -} -impl From<&Path> for CLibPath { - fn from(value: &Path) -> Self { - Self(CString::new(value.to_str().unwrap_or_default()).unwrap()) + pub fn set_log_callback(on_log: F) -> () + where + F: Fn(SdLogLevel, String) + Send + Sync + 'static, + { + // Create a new log callback + let t = ManuallyDrop::new(LogCallback::new(on_log)); + unsafe { diffusion_rs_sys::sd_set_log_callback(t.callback(), t.user_data()) }; } -} -fn output_files(path: PathBuf, batch_size: i32) -> Vec { - if batch_size == 1 { - vec![path.into()] - } else { - (1..=batch_size) - .map(|id| path.join(format!("output_{id}.png")).into()) - .collect() + pub fn set_progress_callback(on_progress: F) -> () + where + F: Fn(i32, i32, f32) + Send + Sync + 'static, + { + // Create a new progress callback + let t = ManuallyDrop::new(ProgressCallback::new(on_progress)); + unsafe { diffusion_rs_sys::sd_set_progress_callback(t.callback(), t.user_data()) }; } -} - -unsafe fn upscale( - upscale_repeats: i32, - upscaler_ctx: Option<*mut upscaler_ctx_t>, - data: sd_image_t, -) -> Result { - match upscaler_ctx { - Some(upscaler_ctx) => { - let upscale_factor = 4; // unused for RealESRGAN_x4plus_anime_6B.pth - let mut current_image = data; - for _ in 0..upscale_repeats { - let upscaled_image = - diffusion_rs_sys::upscale(upscaler_ctx, current_image, upscale_factor); - - if upscaled_image.data.is_null() { - return Err(DiffusionError::Upscaler); - } - free(current_image.data as *mut c_void); - current_image = upscaled_image; + pub fn txt2img(&self, txt2img_config: &Txt2ImgConfig) -> Result, DiffusionError> { + // add loras to prompt as suffix + let prompt: CString = { + let mut prompt = txt2img_config.prompt.clone(); + for lora in txt2img_config.lora_prompt_suffix.iter() { + prompt.push_str(lora); } - Ok(current_image) - } - None => Ok(data), - } -} + CString::new(prompt).expect("Failed to convert prompt to CString") + }; -/// Generate an image with a prompt -pub fn txt2img(mut config: Config) -> Result<(), DiffusionError> { - unsafe { - let prompt: CLibString = match &config.prompt_suffix { - Some(suffix) => format!("{} {suffix}", &config.prompt), - None => config.prompt.clone(), - } - .into(); - let sd_ctx = config.build_sd_ctx(true); - let upscaler_ctx = config.upscaler_ctx(); - let res = { - let slice = diffusion_rs_sys::txt2img( - sd_ctx, - prompt.as_ptr(), - config.negative_prompt.as_ptr(), - config.clip_skip as i32, - config.cfg_scale, - config.guidance, - config.width, - config.height, - config.sampling_method, - config.steps, - config.seed, - config.batch_count, - null(), - config.control_strength, - config.style_ratio, - config.normalize_input, - config.input_id_images.as_ptr(), - config.skip_layer.as_mut_ptr(), - config.skip_layer.len(), - config.slg_scale, - config.skip_layer_start, - config.skip_layer_end, - ); - if slice.is_null() { - return Err(DiffusionError::Forward); - } - let files = output_files(config.output, config.batch_count); - for (id, (img, path)) in slice::from_raw_parts(slice, config.batch_count as usize) - .iter() - .zip(files) - .enumerate() - { - match upscale(config.upscale_repeats, upscaler_ctx, *img) { - Ok(img) => { - let status = stbi_write_png_custom( - path.as_ptr(), - img.width as i32, - img.height as i32, - img.channel as i32, - img.data as *const c_void, - 0, - ); - if status == 0 { - return Err(DiffusionError::StoreImages(id, config.batch_count)); - } - } - Err(err) => { - return Err(err); + let negative_prompt = CString::new(txt2img_config.negative_prompt.clone()) + .expect("Failed to convert negative prompt to CString"); + + //controlnet + let control_image: *const sd_image_t = match txt2img_config.control_cond.as_ref() { + Some(image) => { + if self.config.control_net.is_file() { + &sd_image_t { + data: image.as_ptr().cast_mut(), + width: image.width(), + height: image.height(), + channel: 3, } + } else { + println!("Control net model is null, setting control image to null"); + null() } } + None => { + println!("Control net conditioning image is null, setting control image to null"); + null() + } + }; - //Clean-up slice section - free(slice as *mut c_void); - Ok(()) + let results = unsafe { + diffusion_rs_sys::txt2img( + self.ctx, + prompt.as_ptr(), + negative_prompt.as_ptr(), + txt2img_config.clip_skip, + txt2img_config.cfg_scale, + txt2img_config.guidance, + txt2img_config.eta, + txt2img_config.width, + txt2img_config.height, + txt2img_config.sample_method, + txt2img_config.sample_steps, + txt2img_config.seed, + txt2img_config.batch_count, + control_image, + txt2img_config.control_strength, + txt2img_config.style_strength, + txt2img_config.normalize_input, + pathbuf_to_c_char(&txt2img_config.input_id_images).as_ptr(), + txt2img_config.skip_layer.clone().as_mut_ptr(), + txt2img_config.skip_layer.len(), + txt2img_config.slg_scale, + txt2img_config.skip_layer_start, + txt2img_config.skip_layer_end, + ) }; - //Clean-up CTX section - free_sd_ctx(sd_ctx); - if let Some(upscaler_ctx) = upscaler_ctx { - free_upscaler_ctx(upscaler_ctx); + if results.is_null() { + return Err(DiffusionError::Forward); } - res - } -} - -#[cfg(test)] -mod tests { - use std::path::PathBuf; - - use crate::{api::ConfigBuilderError, util::download_file_hf_hub}; - - use super::{txt2img, ConfigBuilder}; - - #[test] - fn test_required_args_txt2img() { - assert!(ConfigBuilder::default().build().is_err()); - assert!(ConfigBuilder::default() - .model(PathBuf::from("./test.ckpt")) - .build() - .is_err()); - assert!(ConfigBuilder::default() - .prompt("a lovely cat driving a sport car") - .build() - .is_err()); - - assert!(matches!( - ConfigBuilder::default() - .model(PathBuf::from("./test.ckpt")) - .prompt("a lovely cat driving a sport car") - .batch_count(10) - .build(), - Err(ConfigBuilderError::ValidationError(_)) - )); - - ConfigBuilder::default() - .model(PathBuf::from("./test.ckpt")) - .prompt("a lovely cat driving a sport car") - .build() - .unwrap(); + let result_images: Vec = { + let img_count = txt2img_config.batch_count as usize; + let images = unsafe { slice::from_raw_parts(results, img_count) }; + images + .iter() + .filter_map(|sd_img| convert_image(sd_img).ok()) + .collect() + }; - ConfigBuilder::default() - .model(PathBuf::from("./test.ckpt")) - .prompt("a lovely duck drinking water from a bottle") - .batch_count(2) - .output(PathBuf::from("./")) - .build() - .unwrap(); + //Clean-up slice section + unsafe { + free(results as *mut c_void); + } + Ok(result_images) } +} - #[ignore] - #[test] - fn test_txt2img() { - let model_path = - download_file_hf_hub("CompVis/stable-diffusion-v-1-4-original", "sd-v1-4.ckpt") - .unwrap(); - - let upscaler_path = download_file_hf_hub( - "ximso/RealESRGAN_x4plus_anime_6B", - "RealESRGAN_x4plus_anime_6B.pth", - ) - .unwrap(); - let config = ConfigBuilder::default() - .model(model_path) - .prompt("a lovely duck drinking water from a bottle") - .output(PathBuf::from("./output_1.png")) - .upscale_model(upscaler_path) - .upscale_repeats(1) - .batch_count(1) - .build() - .unwrap(); - txt2img(config).unwrap(); +/// Automatic cleanup on drop +impl Drop for ModelCtx { + fn drop(&mut self) { + unsafe { diffusion_rs_sys::free_sd_ctx(self.ctx) }; } } diff --git a/src/lib.rs b/src/lib.rs index 6441c03..2418856 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,13 +1,8 @@ #![doc = include_str!("../README.md")] -/// Safer wrapper around stable-diffusion.cpp bindings -pub mod api; - -/// Presets that automatically download models from -pub mod preset; +#![allow(dead_code)] -/// Add additional resources to [preset::Preset] -pub mod modifier; -pub(crate) mod preset_builder; - -/// Util module -pub mod util; +pub mod api; +pub mod model_config; +pub mod txt2img_config; +pub mod types; +mod utils; diff --git a/src/model_config.rs b/src/model_config.rs new file mode 100644 index 0000000..fc77a27 --- /dev/null +++ b/src/model_config.rs @@ -0,0 +1,150 @@ +use crate::types::{RngFunction, Schedule, WeightType}; +use derive_builder::Builder; + +use std::path::PathBuf; + +#[derive(Builder, Clone, Debug)] +#[builder(setter(into), build_fn(validate = "Self::validate"))] +/// Config struct common to all diffusion methods +pub struct ModelConfig { + /// Path to full model + #[builder(default = "Default::default()")] + pub model: PathBuf, + + /// path to the clip-l text encoder + #[builder(default = "Default::default()")] + pub clip_l: PathBuf, + + /// path to the clip-g text encoder + #[builder(default = "Default::default()")] + pub clip_g: PathBuf, + + /// Path to the t5xxl text encoder + #[builder(default = "Default::default()")] + pub t5xxl: PathBuf, + + /// Path to the standalone diffusion model + #[builder(default = "Default::default()")] + pub diffusion_model: PathBuf, + + /// Path to vae + #[builder(default = "Default::default()")] + pub vae: PathBuf, + + /// Path to taesd. Using Tiny AutoEncoder for fast decoding (lower quality) + #[builder(default = "Default::default()")] + pub taesd: PathBuf, + + /// Path to control net model + #[builder(default = "Default::default()")] + pub control_net: PathBuf, + + /// Lora models directory + #[builder(default = "Default::default()")] + pub lora_model_dir: PathBuf, + + /// Path to embeddings directory + #[builder(default = "Default::default()")] + pub embeddings_dir: PathBuf, + + /// Path to PHOTOMAKER stacked id embeddings + #[builder(default = "Default::default()")] + pub stacked_id_embd_dir: PathBuf, + + //TODO: Add more info here for docs + /// vae decode only (default: false) + #[builder(default = "false")] + pub vae_decode_only: bool, + + /// Process vae in tiles to reduce memory usage (default: false) + #[builder(default = "false")] + pub vae_tiling: bool, + + /// free memory of params immediately after forward (default: false) + #[builder(default = "false")] + pub free_params_immediately: bool, + + /// Number of threads to use during computation (default: 0). + /// If n_threads <= 0, then threads will be set to the number of CPU physical cores. + #[builder( + default = "unsafe { diffusion_rs_sys::get_num_physical_cores() }", + setter(custom) + )] + pub n_threads: i32, + + /// Weight type. If not specified, the default is the type of the weight file + #[builder(default = "WeightType::SD_TYPE_COUNT")] + pub weight_type: WeightType, + + /// RNG type (default: CUDA) + #[builder(default = "RngFunction::CUDA_RNG")] + pub rng_type: RngFunction, + + /// Denoiser sigma schedule (default: DEFAULT) + #[builder(default = "Schedule::DEFAULT")] + pub schedule: Schedule, + + /// keep clip on cpu (for low vram) (default: false) + #[builder(default = "false")] + pub keep_clip_on_cpu: bool, + + /// Keep controlnet in cpu (for low vram) (default: false) + #[builder(default = "false")] + pub keep_control_net_cpu: bool, + + /// Keep vae on cpu (for low vram) (default: false) + #[builder(default = "false")] + pub keep_vae_on_cpu: bool, + + /// Use flash attention in the diffusion model (for low vram). + /// Might lower quality, since it implies converting k and v to f16. + /// This might crash if it is not supported by the backend. + /// must have feature "flash_attention" enabled in the features. + /// (default: false) + #[builder(default = "false")] + pub flash_attention: bool, +} + +unsafe impl Send for ModelConfig {} + +impl ModelConfigBuilder { + pub fn n_threads(&mut self, value: i32) -> &mut Self { + self.n_threads = if value > 0 { + Some(value) + } else { + Some(unsafe { diffusion_rs_sys::get_num_physical_cores() }) + }; + self + } + + fn validate(&self) -> Result<(), ModelConfigBuilderError> { + self.validate_model() + } + + fn validate_model(&self) -> Result<(), ModelConfigBuilderError> { + self.model + .as_ref() + .or(self.diffusion_model.as_ref()) + .map(|_| ()) + .ok_or(ModelConfigBuilderError::UninitializedField( + "Model OR DiffusionModel must be initialized", + )) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_invalid_model_config() { + let config = ModelConfigBuilder::default().build(); + assert!(config.is_err(), "ModelConfig should fail without a model"); + } + + #[test] + fn test_valid_model_config() { + let config = ModelConfigBuilder::default().model("./test.ckpt").build(); + assert!(config.is_ok(), "ModelConfig should succeed with model path"); + } +} diff --git a/src/modifier.rs b/src/modifier.rs deleted file mode 100644 index e3f08fa..0000000 --- a/src/modifier.rs +++ /dev/null @@ -1,168 +0,0 @@ -use hf_hub::api::sync::ApiError; - -use crate::{ - api::{ConfigBuilder, SampleMethod}, - util::download_file_hf_hub, -}; - -/// Add the upscaler -pub fn real_esrgan_x4plus_anime_6_b(mut builder: ConfigBuilder) -> Result { - let upscaler_path = download_file_hf_hub( - "ximso/RealESRGAN_x4plus_anime_6B", - "RealESRGAN_x4plus_anime_6B.pth", - )?; - builder.upscale_model(upscaler_path); - Ok(builder) -} - -/// Apply to avoid black images with xl models -pub fn sdxl_vae_fp16_fix(mut builder: ConfigBuilder) -> Result { - let vae_path = download_file_hf_hub("madebyollin/sdxl-vae-fp16-fix", "sdxl.vae.safetensors")?; - builder.vae(vae_path); - Ok(builder) -} - -/// Apply taesd autoencoder for faster decoding (SD v1/v2) -pub fn taesd(mut builder: ConfigBuilder) -> Result { - let taesd_path = - download_file_hf_hub("madebyollin/taesd", "diffusion_pytorch_model.safetensors")?; - builder.taesd(taesd_path); - Ok(builder) -} - -/// Apply taesd autoencoder for faster decoding (SDXL) -pub fn taesd_xl(mut builder: ConfigBuilder) -> Result { - let taesd_path = - download_file_hf_hub("madebyollin/taesdxl", "diffusion_pytorch_model.safetensors")?; - builder.taesd(taesd_path); - Ok(builder) -} - -/// Apply taesd autoencoder for faster decoding (SD v1/v2) -pub fn hybrid_taesd(mut builder: ConfigBuilder) -> Result { - let taesd_path = download_file_hf_hub( - "cqyan/hybrid-sd-tinyvae", - "diffusion_pytorch_model.safetensors", - )?; - builder.taesd(taesd_path); - Ok(builder) -} - -/// Apply taesd autoencoder for faster decoding (SDXL) -pub fn hybrid_taesd_xl(mut builder: ConfigBuilder) -> Result { - let taesd_path = download_file_hf_hub( - "cqyan/hybrid-sd-tinyvae-xl", - "diffusion_pytorch_model.safetensors", - )?; - builder.taesd(taesd_path); - Ok(builder) -} - -/// Apply to reduce inference steps for SD v1 between 2-8 -/// cfg_scale 1. 4 steps. -pub fn lcm_lora_sd_1_5(mut builder: ConfigBuilder) -> Result { - let lora_path = download_file_hf_hub( - "latent-consistency/lcm-lora-sdv1-5", - "pytorch_lora_weights.safetensors", - )?; - builder.lora_model(&lora_path).cfg_scale(1.).steps(4); - Ok(builder) -} - -/// Apply to reduce inference steps for SD v1 between 2-8 (default 8) -/// Enabled [api::SampleMethod::LCM]. cfg_scale 2. 8 steps. -pub fn lcm_lora_sdxl_base_1_0(mut builder: ConfigBuilder) -> Result { - let lora_path = download_file_hf_hub( - "latent-consistency/lcm-lora-sdxl", - "pytorch_lora_weights.safetensors", - )?; - builder - .lora_model(&lora_path) - .cfg_scale(2.) - .steps(8) - .sampling_method(SampleMethod::LCM); - Ok(builder) -} - -/// Apply Fp8 t5xxl text encoder to reduce memory usage -pub fn t5xxl_fp8_flux_1(mut builder: ConfigBuilder) -> Result { - let t5xxl_path = download_file_hf_hub( - "comfyanonymous/flux_text_encoders", - "t5xxl_fp8_e4m3fn.safetensors", - )?; - - builder.t5xxl(t5xxl_path); - Ok(builder) -} - -/// Apply -/// Default for flux_1_dev/schnell -pub fn t5xxl_fp16_flux_1(mut builder: ConfigBuilder) -> Result { - let t5xxl_path = download_file_hf_hub( - "comfyanonymous/flux_text_encoders", - "t5xxl_fp16.safetensors", - )?; - - builder.t5xxl(t5xxl_path); - Ok(builder) -} - -#[cfg(test)] -mod tests { - use crate::{ - api::txt2img, - preset::{Modifier, Preset, PresetBuilder}, - }; - - use super::{ - hybrid_taesd, hybrid_taesd_xl, lcm_lora_sd_1_5, lcm_lora_sdxl_base_1_0, taesd, taesd_xl, - }; - - static PROMPT: &str = "a lovely duck drinking water from a bottle"; - - fn run(preset: Preset, m: Modifier) { - let config = PresetBuilder::default() - .preset(preset) - .prompt(PROMPT) - .with_modifier(m) - .build() - .unwrap(); - txt2img(config).unwrap(); - } - - #[ignore] - #[test] - fn test_taesd() { - run(Preset::StableDiffusion1_5, taesd); - } - - #[ignore] - #[test] - fn test_taesd_xl() { - run(Preset::SDXLTurbo1_0Fp16, taesd_xl); - } - - #[ignore] - #[test] - fn test_hybrid_taesd() { - run(Preset::StableDiffusion1_5, hybrid_taesd); - } - - #[ignore] - #[test] - fn test_hybrid_taesd_xl() { - run(Preset::SDXLTurbo1_0Fp16, hybrid_taesd_xl); - } - - #[ignore] - #[test] - fn test_lcm_lora_sd_1_5() { - run(Preset::StableDiffusion1_5, lcm_lora_sd_1_5); - } - - #[ignore] - #[test] - fn test_lcm_lora_sdxl_base_1_0() { - run(Preset::SDXLBase1_0, lcm_lora_sdxl_base_1_0); - } -} diff --git a/src/preset.rs b/src/preset.rs deleted file mode 100644 index cc76129..0000000 --- a/src/preset.rs +++ /dev/null @@ -1,234 +0,0 @@ -use derive_builder::Builder; -use hf_hub::api::sync::ApiError; - -use crate::{ - api::{self, Config, ConfigBuilder, ConfigBuilderError}, - preset_builder::{ - flux_1_dev, flux_1_mini, flux_1_schnell, juggernaut_xl_11, sd_turbo, sdxl_base_1_0, - sdxl_turbo_1_0_fp16, stable_diffusion_1_4, stable_diffusion_1_5, stable_diffusion_2_1, - stable_diffusion_3_5_large_fp16, stable_diffusion_3_5_large_turbo_fp16, - stable_diffusion_3_5_medium_fp16, stable_diffusion_3_medium_fp16, - }, -}; - -#[non_exhaustive] -#[derive(Debug, Clone, Copy)] -/// Models ready to use -pub enum Preset { - StableDiffusion1_4, - StableDiffusion1_5, - /// model. - /// Vae-tiling enabled. 768x768. - StableDiffusion2_1, - /// Requires access rights to providing a token via [crate::util::set_hf_token] - /// Vae-tiling enabled. 1024x1024. Enabled [api::SampleMethod::EULER]. 30 steps. - StableDiffusion3MediumFp16, - /// Requires access rights to providing a token via [crate::util::set_hf_token] - /// Vae-tiling enabled. 1024x1024. Enabled [api::SampleMethod::EULER]. cfg_scale 4.5. 40 steps. - StableDiffusion3_5MediumFp16, - /// Requires access rights to providing a token via [crate::util::set_hf_token] - /// Vae-tiling enabled. 1024x1024. Enabled [api::SampleMethod::EULER]. cfg_scale 4.5. 28 steps. - StableDiffusion3_5LargeFp16, - /// Requires access rights to providing a token via [crate::util::set_hf_token] - /// Vae-tiling enabled. 1024x1024. Enabled [api::SampleMethod::EULER]. cfg_scale 0. 4 steps. - StableDiffusion3_5LargeTurboFp16, - SDXLBase1_0, - /// cfg_scale 1. guidance 0. 4 steps - SDTurbo, - /// cfg_scale 1. guidance 0. 4 steps - SDXLTurbo1_0Fp16, - /// Requires access rights to providing a token via [crate::util::set_hf_token] - /// Vae-tiling enabled. 1024x1024. Enabled [api::SampleMethod::EULER]. 28 steps. - Flux1Dev(api::WeightType), - /// Requires access rights to providing a token via [crate::util::set_hf_token] - /// Vae-tiling enabled. 1024x1024. Enabled [api::SampleMethod::EULER]. 4 steps. - Flux1Schnell(api::WeightType), - /// A 3.2B param rectified flow transformer distilled from FLUX.1 [dev] https://huggingface.co/TencentARC/flux-mini - /// Vae-tiling enabled. 512x512. Enabled [api::SampleMethod::EULER]. 28 steps. - Flux1Mini, - /// Requires access rights to providing a token via [crate::util::set_hf_token] - /// Vae-tiling enabled. 1024x1024. Enabled [api::SampleMethod::DPM2]. guidance 6. 20 steps - JuggernautXL11, -} - -impl Preset { - fn try_config_builder(self) -> Result { - match self { - Preset::StableDiffusion1_4 => stable_diffusion_1_4(), - Preset::StableDiffusion1_5 => stable_diffusion_1_5(), - Preset::StableDiffusion2_1 => stable_diffusion_2_1(), - Preset::StableDiffusion3MediumFp16 => stable_diffusion_3_medium_fp16(), - Preset::SDXLBase1_0 => sdxl_base_1_0(), - Preset::Flux1Dev(sd_type_t) => flux_1_dev(sd_type_t), - Preset::Flux1Schnell(sd_type_t) => flux_1_schnell(sd_type_t), - Preset::SDTurbo => sd_turbo(), - Preset::SDXLTurbo1_0Fp16 => sdxl_turbo_1_0_fp16(), - Preset::StableDiffusion3_5LargeFp16 => stable_diffusion_3_5_large_fp16(), - Preset::StableDiffusion3_5MediumFp16 => stable_diffusion_3_5_medium_fp16(), - Preset::StableDiffusion3_5LargeTurboFp16 => stable_diffusion_3_5_large_turbo_fp16(), - Preset::JuggernautXL11 => juggernaut_xl_11(), - Preset::Flux1Mini => flux_1_mini(), - } - } -} - -/// Helper functions that modifies the [ConfigBuilder] See [crate::modifier] -pub type Modifier = fn(ConfigBuilder) -> Result; - -#[derive(Debug, Clone, Builder)] -#[builder( - name = "PresetBuilder", - setter(into), - build_fn(name = "internal_build", private, error = "ConfigBuilderError") -)] -/// Helper struct for [ConfigBuilder] -pub struct PresetConfig { - prompt: String, - preset: Preset, - #[builder(private, default = "Vec::new()")] - modifiers: Vec Result>, -} - -impl PresetBuilder { - /// Add modifier that will apply in sequence - pub fn with_modifier(&mut self, f: Modifier) -> &mut Self { - if self.modifiers.is_none() { - self.modifiers = Some(Vec::new()); - } - self.modifiers.as_mut().unwrap().push(f); - self - } - - pub fn build(&mut self) -> Result { - let preset = self.internal_build()?; - let config: ConfigBuilder = preset - .try_into() - .map_err(|err: ApiError| ConfigBuilderError::ValidationError(err.to_string()))?; - config.build() - } -} - -impl TryFrom for ConfigBuilder { - type Error = ApiError; - - fn try_from(value: PresetConfig) -> Result { - let mut config_builder = value.preset.try_config_builder()?; - for m in value.modifiers { - config_builder = m(config_builder)?; - } - config_builder.prompt(value.prompt); - Ok(config_builder) - } -} - -#[cfg(test)] -mod tests { - use crate::{ - api::{self, txt2img}, - util::set_hf_token, - }; - - use super::{Preset, PresetBuilder}; - static PROMPT: &str = "a lovely duck drinking water from a bottle"; - - fn run(preset: Preset) { - let config = PresetBuilder::default() - .preset(preset) - .prompt(PROMPT) - .build() - .unwrap(); - txt2img(config).unwrap(); - } - - #[ignore] - #[test] - fn test_stable_diffusion_1_4() { - run(Preset::StableDiffusion1_4); - } - - #[ignore] - #[test] - fn test_stable_diffusion_1_5() { - run(Preset::StableDiffusion1_5); - } - - #[ignore] - #[test] - fn test_stable_diffusion_2_1() { - run(Preset::StableDiffusion2_1); - } - - #[ignore] - #[test] - fn test_stable_diffusion_3_medium_fp16() { - set_hf_token(include_str!("../token.txt")); - run(Preset::StableDiffusion3MediumFp16); - } - - #[ignore] - #[test] - fn test_sdxl_base_1_0() { - run(Preset::SDXLBase1_0); - } - - #[ignore] - #[test] - fn test_flux_1_dev() { - set_hf_token(include_str!("../token.txt")); - run(Preset::Flux1Dev(api::WeightType::SD_TYPE_Q2_K)); - } - - #[ignore] - #[test] - fn test_flux_1_schnell() { - set_hf_token(include_str!("../token.txt")); - run(Preset::Flux1Schnell(api::WeightType::SD_TYPE_Q2_K)); - } - - #[ignore] - #[test] - fn test_sd_turbo() { - run(Preset::SDTurbo); - } - - #[ignore] - #[test] - fn test_sdxl_turbo_1_0_fp16() { - run(Preset::SDXLTurbo1_0Fp16); - } - - #[ignore] - #[test] - fn test_stable_diffusion_3_5_medium_fp16() { - set_hf_token(include_str!("../token.txt")); - run(Preset::StableDiffusion3_5MediumFp16); - } - - #[ignore] - #[test] - fn test_stable_diffusion_3_5_large_fp16() { - set_hf_token(include_str!("../token.txt")); - run(Preset::StableDiffusion3_5LargeFp16); - } - - #[ignore] - #[test] - fn test_stable_diffusion_3_5_large_turbo_fp16() { - set_hf_token(include_str!("../token.txt")); - run(Preset::StableDiffusion3_5LargeTurboFp16); - } - - #[ignore] - #[test] - fn test_juggernaut_xl_11() { - set_hf_token(include_str!("../token.txt")); - run(Preset::JuggernautXL11); - } - - #[ignore] - #[test] - fn test_flux_1_mini() { - set_hf_token(include_str!("../token.txt")); - run(Preset::Flux1Mini); - } -} diff --git a/src/preset_builder.rs b/src/preset_builder.rs deleted file mode 100644 index a2c6c35..0000000 --- a/src/preset_builder.rs +++ /dev/null @@ -1,255 +0,0 @@ -use std::path::PathBuf; - -use crate::{ - api::{self, SampleMethod}, - modifier::{sdxl_vae_fp16_fix, t5xxl_fp16_flux_1, t5xxl_fp8_flux_1}, -}; -use hf_hub::api::sync::ApiError; - -use crate::{api::ConfigBuilder, util::download_file_hf_hub}; - -pub fn stable_diffusion_1_4() -> Result { - let model_path = - download_file_hf_hub("CompVis/stable-diffusion-v-1-4-original", "sd-v1-4.ckpt")?; - - let mut config = ConfigBuilder::default(); - - config.model(model_path); - - Ok(config) -} - -pub fn stable_diffusion_1_5() -> Result { - let model_path = download_file_hf_hub( - "stablediffusiontutorials/stable-diffusion-v1.5", - "v1-5-pruned-emaonly.safetensors", - )?; - - let mut config = ConfigBuilder::default(); - - config.model(model_path); - - Ok(config) -} - -pub fn stable_diffusion_2_1() -> Result { - let model_path = download_file_hf_hub( - "stabilityai/stable-diffusion-2-1", - "v2-1_768-nonema-pruned.safetensors", - )?; - - let mut config = ConfigBuilder::default(); - - config - .model(model_path) - .vae_tiling(true) - .steps(25) - .height(768) - .width(768); - - Ok(config) -} - -pub fn stable_diffusion_3_medium_fp16() -> Result { - let model_path = download_file_hf_hub( - "stabilityai/stable-diffusion-3-medium", - "sd3_medium_incl_clips_t5xxlfp16.safetensors", - )?; - - let mut config = ConfigBuilder::default(); - - config - .model(model_path) - .vae_tiling(true) - .cfg_scale(4.5) - .sampling_method(SampleMethod::EULER) - .steps(30) - .height(1024) - .width(1024); - - Ok(config) -} - -pub fn sdxl_base_1_0() -> Result { - let model_path = download_file_hf_hub( - "stabilityai/stable-diffusion-xl-base-1.0", - "sd_xl_base_1.0.safetensors", - )?; - - let mut config = ConfigBuilder::default(); - - config - .model(model_path) - .vae_tiling(true) - .height(1024) - .width(1024); - sdxl_vae_fp16_fix(config) -} - -pub fn flux_1_dev(sd_type: api::WeightType) -> Result { - let model_path = flux_1_model_weight("dev", sd_type)?; - let mut builder = flux_1("dev", 28)?; - - builder.diffusion_model(model_path); - t5xxl_fp16_flux_1(builder) -} - -pub fn flux_1_schnell(sd_type: api::WeightType) -> Result { - let model_path = flux_1_model_weight("schnell", sd_type)?; - let mut builder = flux_1("schnell", 4)?; - - builder.diffusion_model(model_path); - t5xxl_fp16_flux_1(builder) -} - -fn flux_1_model_weight(model: &str, sd_type: api::WeightType) -> Result { - check_flux_type(sd_type); - let weight_type = flux_type_to_model(sd_type); - download_file_hf_hub( - format!("leejet/FLUX.1-{model}-gguf").as_str(), - format!("flux1-{model}-{}.gguf", weight_type).as_str(), - ) -} - -fn flux_1(vae_model: &str, steps: i32) -> Result { - let mut config = ConfigBuilder::default(); - let vae_path = download_file_hf_hub( - format!("black-forest-labs/FLUX.1-{vae_model}").as_str(), - "ae.safetensors", - )?; - let clip_l_path = - download_file_hf_hub("comfyanonymous/flux_text_encoders", "clip_l.safetensors")?; - - config - .vae(vae_path) - .clip_l(clip_l_path) - .vae_tiling(true) - .cfg_scale(1.) - .sampling_method(SampleMethod::EULER) - .steps(steps) - .height(1024) - .width(1024); - - Ok(config) -} - -fn check_flux_type(sd_type: api::WeightType) { - assert!( - sd_type == api::WeightType::SD_TYPE_Q2_K - || sd_type == api::WeightType::SD_TYPE_Q3_K - || sd_type == api::WeightType::SD_TYPE_Q4_0 - || sd_type == api::WeightType::SD_TYPE_Q4_K - || sd_type == api::WeightType::SD_TYPE_Q8_0 - ); -} - -fn flux_type_to_model(sd_type: api::WeightType) -> &'static str { - match sd_type { - api::WeightType::SD_TYPE_Q3_K => "q3_k", - api::WeightType::SD_TYPE_Q2_K => "q2_k", - api::WeightType::SD_TYPE_Q4_0 => "q4_0", - api::WeightType::SD_TYPE_Q4_K => "q4_k", - api::WeightType::SD_TYPE_Q8_0 => "q8_0", - _ => "not_supported", - } -} - -pub fn sd_turbo() -> Result { - let model_path = download_file_hf_hub("stabilityai/sd-turbo", "sd_turbo.safetensors")?; - - let mut config = ConfigBuilder::default(); - - config.model(model_path).guidance(0.).cfg_scale(1.).steps(4); - - Ok(config) -} - -pub fn sdxl_turbo_1_0_fp16() -> Result { - let model_path = - download_file_hf_hub("stabilityai/sdxl-turbo", "sd_xl_turbo_1.0_fp16.safetensors")?; - - let mut config = ConfigBuilder::default(); - - config.model(model_path).guidance(0.).cfg_scale(1.).steps(4); - sdxl_vae_fp16_fix(config) -} - -pub fn stable_diffusion_3_5_large_fp16() -> Result { - stable_diffusion_3_5("large", "large", 28, 4.5) -} - -pub fn stable_diffusion_3_5_large_turbo_fp16() -> Result { - stable_diffusion_3_5("large-turbo", "large_turbo", 4, 0.) -} - -pub fn stable_diffusion_3_5_medium_fp16() -> Result { - stable_diffusion_3_5("medium", "medium", 40, 4.5) -} - -pub fn stable_diffusion_3_5( - model: &str, - file_model: &str, - steps: i32, - cfg_scale: f32, -) -> Result { - let model_path = download_file_hf_hub( - format!("stabilityai/stable-diffusion-3.5-{model}").as_str(), - format!("sd3.5_{file_model}.safetensors").as_str(), - )?; - - let clip_g_path = download_file_hf_hub( - "Comfy-Org/stable-diffusion-3.5-fp8", - "text_encoders/clip_g.safetensors", - )?; - let clip_l_path = download_file_hf_hub( - "Comfy-Org/stable-diffusion-3.5-fp8", - "text_encoders/clip_l.safetensors", - )?; - let t5xxl_path = download_file_hf_hub( - "Comfy-Org/stable-diffusion-3.5-fp8", - "text_encoders/t5xxl_fp16.safetensors", - )?; - - let mut config = ConfigBuilder::default(); - - config - .diffusion_model(model_path) - .clip_l(clip_l_path) - .clip_g(clip_g_path) - .t5xxl(t5xxl_path) - .vae_tiling(true) - .cfg_scale(cfg_scale) - .sampling_method(SampleMethod::EULER) - .steps(steps) - .height(1024) - .width(1024); - - Ok(config) -} - -pub fn juggernaut_xl_11() -> Result { - let model_path = download_file_hf_hub( - "RunDiffusion/Juggernaut-XI-v11", - "Juggernaut-XI-byRunDiffusion.safetensors", - )?; - - let mut config = ConfigBuilder::default(); - - config - .model(model_path) - .vae_tiling(true) - .sampling_method(SampleMethod::DPM2) - .steps(20) - .guidance(6.) - .height(1024) - .width(1024); - - Ok(config) -} - -pub fn flux_1_mini() -> Result { - let model_path = download_file_hf_hub("TencentARC/flux-mini", "flux-mini.safetensors")?; - let mut builder = flux_1("dev", 28)?; - builder.diffusion_model(model_path).width(512).height(512); - t5xxl_fp8_flux_1(builder) -} diff --git a/src/txt2img_config.rs b/src/txt2img_config.rs new file mode 100644 index 0000000..e879f5f --- /dev/null +++ b/src/txt2img_config.rs @@ -0,0 +1,138 @@ +use std::path::PathBuf; + +use crate::types::SampleMethod; +use derive_builder::Builder; +use image::RgbImage; + +#[derive(Builder, Debug, Clone)] +#[builder(setter(into, strip_option), build_fn(validate = "Self::validate"))] +/// txt2img config +pub struct Txt2ImgConfig { + /// Prompt to generate image from + pub prompt: String, + + /// Suffix that needs to be added to prompt (e.g. lora model) + #[builder(default = "Default::default()", private)] + pub lora_prompt_suffix: Vec, + + /// The negative prompt (default: "") + #[builder(default = "\"\".into()")] + pub negative_prompt: String, + + /// Ignore last layers of CLIP network; 1 ignores none, 2 ignores one layer (default: -1) + /// <= 0 represents unspecified, will be 1 for SD1.x, 2 for SD2.x + #[builder(default = "0")] + pub clip_skip: i32, + + /// Unconditional guidance scale (default: 7.0) + #[builder(default = "7.0")] + pub cfg_scale: f32, + + /// Guidance (default: 3.5) for Flux/DiT models + #[builder(default = "3.5")] + pub guidance: f32, + + /// eta in DDIM, only for DDIM and TCD: (default: 0) + #[builder(default = "0.0")] + pub eta: f32, + + /// Image height, in pixel space (default: 512) + #[builder(default = "512")] + pub height: i32, + + /// Image width, in pixel space (default: 512) + #[builder(default = "512")] + pub width: i32, + + /// Sampling-method (default: EULER_A) + #[builder(default = "SampleMethod::EULER_A")] + pub sample_method: SampleMethod, + + /// Number of sample steps (default: 20) + #[builder(default = "20")] + pub sample_steps: i32, + + /// RNG seed (default: 42, use random seed for < 0) + #[builder(default = "42")] + pub seed: i64, + + /// Number of images to generate (default: 1) + #[builder(default = "1")] + pub batch_count: i32, + + #[builder(default = "None")] + pub control_cond: Option, + + /// Strength to apply Control Net (default: 0.9) + /// 1.0 corresponds to full destruction of information in init + #[builder(default = "0.9")] + pub control_strength: f32, + + /// Strength for keeping input identity (default: 20%) + #[builder(default = "20.0")] + pub style_strength: f32, + + /// Normalize PHOTOMAKER input id images + #[builder(default = "false")] + pub normalize_input: bool, + + /// Path to PHOTOMAKER input id images dir + #[builder(default = "Default::default()")] + pub input_id_images: PathBuf, + + /// Layers to skip for SLG steps: (default: [7,8,9]) + #[builder(default = "vec![7, 8, 9]")] + pub skip_layer: Vec, + + /// skip layer guidance (SLG) scale, only for DiT models: (default: 0) + /// 0 means disabled, a value of 2.5 is nice for sd3.5 medium + #[builder(default = "0.0")] + pub slg_scale: f32, + + /// SLG enabling point: (default: 0.01) + #[builder(default = "0.01")] + pub skip_layer_start: f32, + + /// SLG disabling point: (default: 0.2) + #[builder(default = "0.2")] + pub skip_layer_end: f32, +} + +impl Txt2ImgConfigBuilder { + fn validate(&self) -> Result<(), Txt2ImgConfigBuilderError> { + self.validate_prompt() + } + + fn validate_prompt(&self) -> Result<(), Txt2ImgConfigBuilderError> { + self.prompt + .as_ref() + .map(|_| ()) + .ok_or(Txt2ImgConfigBuilderError::UninitializedField("Prompt")) + } + + pub fn add_lora_model(&mut self, filename: &str, strength: f32) -> &mut Self { + self.lora_prompt_suffix + .get_or_insert_with(Vec::new) + .push(format!("")); + self + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_invalid_txt2img_config() { + let config = Txt2ImgConfigBuilder::default().build(); + assert!(config.is_err(), "Txt2ImgConfig should fail without prompt"); + } + + #[test] + fn test_valid_txt2img_config() { + let config = Txt2ImgConfigBuilder::default() + .prompt("testing prompt") + .build(); + assert!(config.is_ok(), "Txt2ImgConfig should succeed with prompt"); + } +} diff --git a/src/types.rs b/src/types.rs new file mode 100644 index 0000000..6da6480 --- /dev/null +++ b/src/types.rs @@ -0,0 +1,161 @@ +use std::ffi::CStr; +use std::ffi::c_char; +use std::ffi::c_void; + +/// Specify the range function +pub use diffusion_rs_sys::rng_type_t as RngFunction; + +/// Denoiser sigma schedule +pub use diffusion_rs_sys::schedule_t as Schedule; + +/// Weight type +pub use diffusion_rs_sys::sd_type_t as WeightType; + +/// Sampling methods +pub use diffusion_rs_sys::sample_method_t as SampleMethod; + +/// Log Level +pub use diffusion_rs_sys::sd_log_level_t as SdLogLevel; + +#[non_exhaustive] +#[derive(thiserror::Error, Debug)] +/// Error that can occurs while forwarding models +pub enum DiffusionError { + #[error("The underling stablediffusion.cpp function returned NULL")] + Forward, + #[error("The underling stbi_write_image function returned 0 while saving image {0}/{1})")] + StoreImages(usize, i32), + #[error("The underling upscaler model returned a NULL image")] + Upscaler, + #[error("raw_ctx is None")] + NoContext, + #[error("new_sd_ctx returned null")] + NewContextFailure, + #[error("SD image conversion error: {0}")] + SDImageError(#[from] SDImageError), +} + +#[non_exhaustive] +#[derive(Debug, thiserror::Error)] +pub enum SDImageError { + #[error("Failed to convert image buffer to Rust type")] + AllocationError, + #[error("The image buffer has a different length than expected")] + DifferentLength, +} + +#[derive(Debug)] +pub struct LogCallback { + callback: Option, + free_user_data: unsafe fn(*mut c_void), + user_data: *mut c_void, +} + +impl LogCallback { + pub fn new(f: F) -> Self { + unsafe extern "C" fn callback( + level: SdLogLevel, + text: *const c_char, + data: *mut c_void, + ) { + let f: &F = unsafe { &*data.cast_const().cast::() }; + // convert input and pass to closure + let msg = unsafe { CStr::from_ptr(text) } + .to_str() + .unwrap_or("LOG ERROR: Invalid UTF-8"); + f(level, msg.to_string()); + } + + unsafe fn free_user_data(user_data: *mut c_void) { + let user_data = user_data.cast::(); + unsafe { _ = Box::from_raw(user_data) } + } + + let user_data = Box::into_raw(Box::new(f)); + + Self { + callback: Some(callback::), + free_user_data: free_user_data::, + user_data: user_data.cast(), + } + } + + pub fn user_data(&self) -> *mut c_void { + self.user_data + } + + pub fn callback(&self) -> Option { + self.callback + } +} + +// SAFETY: A Callback can only be constructed with +// LogCallback::new, which requires F to be Send and Sync. +unsafe impl Send for LogCallback {} +unsafe impl Sync for LogCallback {} + +impl Drop for LogCallback { + fn drop(&mut self) { + unsafe { (self.free_user_data)(self.user_data) } + } +} + +#[derive(Debug)] +pub struct ProgressCallback { + callback: Option, + free_user_data: unsafe fn(*mut c_void), + user_data: *mut c_void, +} + +impl ProgressCallback { + pub fn new(f: F) -> Self { + unsafe extern "C" fn callback( + step: i32, + steps: i32, + time: f32, + data: *mut c_void, + ) { + let f: &F = unsafe { &*data.cast_const().cast::() }; + // convert input and pass to closure + f(step, steps, time); + } + + unsafe fn free_user_data(user_data: *mut c_void) { + let user_data = user_data.cast::(); + unsafe { _ = Box::from_raw(user_data) } + } + + let user_data = Box::into_raw(Box::new(f)); + + Self { + callback: Some(callback::), + free_user_data: free_user_data::, + user_data: user_data.cast(), + } + } + + pub fn user_data(&self) -> *mut c_void { + self.user_data + } + + pub fn callback(&self) -> Option { + self.callback + } +} + +// SAFETY: A Callback can only be constructed with +// ProgressCallback::new, which requires F to be Send and Sync. +unsafe impl Send for ProgressCallback {} +unsafe impl Sync for ProgressCallback {} + +impl Drop for ProgressCallback { + fn drop(&mut self) { + unsafe { (self.free_user_data)(self.user_data) } + } +} + +type UnsafeLogCallbackFn = + unsafe extern "C" fn(level: SdLogLevel, text: *const c_char, data: *mut c_void); + +type UnsafeProgressCallbackFn = + unsafe extern "C" fn(step: i32, steps: i32, time: f32, data: *mut c_void); diff --git a/src/util.rs b/src/util.rs deleted file mode 100644 index acdd7a7..0000000 --- a/src/util.rs +++ /dev/null @@ -1,25 +0,0 @@ -use std::{ - path::PathBuf, - sync::{OnceLock, RwLock}, -}; - -use hf_hub::api::sync::{ApiBuilder, ApiError}; - -static TOKEN: OnceLock> = OnceLock::new(); - -/// Set the huggingface hub token to access "protected" models. See -pub fn set_hf_token(token: &str) { - let guard = TOKEN.get_or_init(|| RwLock::new(Default::default())); - let mut data = guard.write().unwrap(); - *data = token.to_owned(); -} - -/// Download file from huggingface hub -pub fn download_file_hf_hub(repo: &str, file: &str) -> Result { - let token = TOKEN.get().map(|token| token.read().unwrap().to_owned()); - let repo = ApiBuilder::new() - .with_token(token) - .build()? - .model(repo.to_string()); - repo.get(file) -} diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..e91646f --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,29 @@ +use image::ImageBuffer; +use image::Rgb; +use image::RgbImage; +use std::ffi::CString; +use std::path::PathBuf; +use std::slice; + +use diffusion_rs_sys::sd_image_t; + +use crate::types::SDImageError; + +pub fn pathbuf_to_c_char(path: &PathBuf) -> CString { + let path_str = path + .to_str() + .expect("PathBuf contained non-UTF-8 characters"); + CString::new(path_str).expect("CString conversion failed") +} + +pub fn convert_image(sd_image: &sd_image_t) -> Result { + let len = (sd_image.width * sd_image.height * sd_image.channel) as usize; + let raw_pixels = unsafe { slice::from_raw_parts(sd_image.data, len) }; + let buffer = raw_pixels.to_vec(); + let buffer = + ImageBuffer::, _>::from_raw(sd_image.width as u32, sd_image.height as u32, buffer); + Ok(match buffer { + Some(buffer) => RgbImage::from(buffer), + None => return Err(SDImageError::AllocationError), + }) +} diff --git a/sys/Cargo.toml b/sys/Cargo.toml index 1fcbec7..6c65fda 100644 --- a/sys/Cargo.toml +++ b/sys/Cargo.toml @@ -36,10 +36,8 @@ hipblas = [] metal = [] vulkan = [] sycl = [] -flashattn = [] [build-dependencies] -cc = "1.1.31" cmake = "0.1.51" bindgen = "0.71.1" fs_extra = "1.3.0" diff --git a/sys/build.rs b/sys/build.rs index 4b8d875..7ddc6c3 100644 --- a/sys/build.rs +++ b/sys/build.rs @@ -17,12 +17,10 @@ fn main() { } println!("cargo:rerun-if-changed=wrapper.h"); - println!("cargo:rerun-if-changed=stb_image_write.c"); // Copy stable-diffusion code into the build script directory let out = PathBuf::from(env::var("OUT_DIR").unwrap()); let diffusion_root = out.join("stable-diffusion.cpp/"); - let stb_write_image_src = diffusion_root.join("thirdparty/stb_image_write.c"); if !diffusion_root.exists() { create_dir_all(&diffusion_root).unwrap(); @@ -33,16 +31,6 @@ fn main() { e ) }); - fs::copy("./stb_image_write.c", &stb_write_image_src).unwrap_or_else(|e| { - panic!( - "Failed to copy stb_image_write to {}: {}", - stb_write_image_src.display(), - e - ) - }); - - remove_default_params_stb(&diffusion_root.join("thirdparty/stb_image_write.h")) - .unwrap_or_else(|e| panic!("Failed to remove default parameters from stb: {}", e)); } // Bindgen @@ -194,11 +182,6 @@ fn main() { config.define("SD_SYCL", "ON"); } - #[cfg(feature = "flashattn")] - { - config.define("SD_FLASH_ATTN", "ON"); - } - // Build stable-diffusion config .profile("Release") @@ -210,11 +193,6 @@ fn main() { let destination = config.build(); - // Build stb write image - let mut builder = cc::Build::new(); - - builder.file(stb_write_image_src).compile("stbwriteimage"); - add_link_search_path(&out.join("lib")).unwrap(); add_link_search_path(&out.join("build")).unwrap(); add_link_search_path(&out).unwrap(); @@ -266,9 +244,3 @@ fn get_cpp_link_stdlib(target: &str) -> Option<&'static str> { Some("stdc++") } } - -fn remove_default_params_stb(file: &Path) -> std::io::Result<()> { - let data = fs::read_to_string(file)?; - let new_data = data.replace("const char* parameters = NULL", "const char* parameters"); - fs::write(file, new_data) -} diff --git a/sys/src/bindings.rs b/sys/src/bindings.rs index e7dbde9..7f8b28e 100644 --- a/sys/src/bindings.rs +++ b/sys/src/bindings.rs @@ -1,996 +1,1083 @@ /* automatically generated by rust-bindgen 0.71.1 */ pub const __bool_true_false_are_defined: u32 = 1; -pub const false_: u32 = 0; pub const true_: u32 = 1; -pub const _VCRT_COMPILER_PREPROCESSOR: u32 = 1; -pub const _SAL_VERSION: u32 = 20; -pub const __SAL_H_VERSION: u32 = 180000000; -pub const _USE_DECLSPECS_FOR_SAL: u32 = 0; -pub const _USE_ATTRIBUTES_FOR_SAL: u32 = 0; -pub const _CRT_PACKING: u32 = 8; -pub const _HAS_EXCEPTIONS: u32 = 1; -pub const _STL_LANG: u32 = 0; -pub const _HAS_CXX17: u32 = 0; -pub const _HAS_CXX20: u32 = 0; -pub const _HAS_CXX23: u32 = 0; -pub const _HAS_NODISCARD: u32 = 0; -pub const _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE: u32 = 1; -pub const _CRT_BUILD_DESKTOP_APP: u32 = 1; -pub const _ARGMAX: u32 = 100; -pub const _CRT_INT_MAX: u32 = 2147483647; -pub const _CRT_FUNCTIONS_REQUIRED: u32 = 1; -pub const _CRT_HAS_CXX17: u32 = 0; -pub const _CRT_HAS_C11: u32 = 1; -pub const _CRT_INTERNAL_NONSTDC_NAMES: u32 = 1; -pub const __STDC_SECURE_LIB__: u32 = 200411; -pub const __GOT_SECURE_LIB__: u32 = 200411; -pub const __STDC_WANT_SECURE_LIB__: u32 = 1; -pub const _SECURECRT_FILL_BUFFER_PATTERN: u32 = 254; -pub const _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES: u32 = 0; -pub const _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT: u32 = 0; -pub const _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES: u32 = 1; -pub const _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_MEMORY: u32 = 0; -pub const _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES_MEMORY: u32 = 0; -pub const WCHAR_MIN: u32 = 0; -pub const WCHAR_MAX: u32 = 65535; -pub const WINT_MIN: u32 = 0; -pub const WINT_MAX: u32 = 65535; -pub const EPERM: u32 = 1; -pub const ENOENT: u32 = 2; -pub const ESRCH: u32 = 3; -pub const EINTR: u32 = 4; -pub const EIO: u32 = 5; -pub const ENXIO: u32 = 6; -pub const E2BIG: u32 = 7; -pub const ENOEXEC: u32 = 8; -pub const EBADF: u32 = 9; -pub const ECHILD: u32 = 10; -pub const EAGAIN: u32 = 11; -pub const ENOMEM: u32 = 12; -pub const EACCES: u32 = 13; -pub const EFAULT: u32 = 14; -pub const EBUSY: u32 = 16; -pub const EEXIST: u32 = 17; -pub const EXDEV: u32 = 18; -pub const ENODEV: u32 = 19; -pub const ENOTDIR: u32 = 20; -pub const EISDIR: u32 = 21; -pub const ENFILE: u32 = 23; -pub const EMFILE: u32 = 24; -pub const ENOTTY: u32 = 25; -pub const EFBIG: u32 = 27; -pub const ENOSPC: u32 = 28; -pub const ESPIPE: u32 = 29; -pub const EROFS: u32 = 30; -pub const EMLINK: u32 = 31; -pub const EPIPE: u32 = 32; -pub const EDOM: u32 = 33; -pub const EDEADLK: u32 = 36; -pub const ENAMETOOLONG: u32 = 38; -pub const ENOLCK: u32 = 39; -pub const ENOSYS: u32 = 40; -pub const ENOTEMPTY: u32 = 41; -pub const EINVAL: u32 = 22; -pub const ERANGE: u32 = 34; -pub const EILSEQ: u32 = 42; -pub const STRUNCATE: u32 = 80; -pub const EDEADLOCK: u32 = 36; -pub const EADDRINUSE: u32 = 100; -pub const EADDRNOTAVAIL: u32 = 101; -pub const EAFNOSUPPORT: u32 = 102; -pub const EALREADY: u32 = 103; -pub const EBADMSG: u32 = 104; -pub const ECANCELED: u32 = 105; -pub const ECONNABORTED: u32 = 106; -pub const ECONNREFUSED: u32 = 107; -pub const ECONNRESET: u32 = 108; -pub const EDESTADDRREQ: u32 = 109; -pub const EHOSTUNREACH: u32 = 110; -pub const EIDRM: u32 = 111; -pub const EINPROGRESS: u32 = 112; -pub const EISCONN: u32 = 113; -pub const ELOOP: u32 = 114; -pub const EMSGSIZE: u32 = 115; -pub const ENETDOWN: u32 = 116; -pub const ENETRESET: u32 = 117; -pub const ENETUNREACH: u32 = 118; -pub const ENOBUFS: u32 = 119; -pub const ENODATA: u32 = 120; -pub const ENOLINK: u32 = 121; -pub const ENOMSG: u32 = 122; -pub const ENOPROTOOPT: u32 = 123; -pub const ENOSR: u32 = 124; -pub const ENOSTR: u32 = 125; -pub const ENOTCONN: u32 = 126; -pub const ENOTRECOVERABLE: u32 = 127; -pub const ENOTSOCK: u32 = 128; -pub const ENOTSUP: u32 = 129; -pub const EOPNOTSUPP: u32 = 130; -pub const EOTHER: u32 = 131; -pub const EOVERFLOW: u32 = 132; -pub const EOWNERDEAD: u32 = 133; -pub const EPROTO: u32 = 134; -pub const EPROTONOSUPPORT: u32 = 135; -pub const EPROTOTYPE: u32 = 136; -pub const ETIME: u32 = 137; -pub const ETIMEDOUT: u32 = 138; -pub const ETXTBSY: u32 = 139; -pub const EWOULDBLOCK: u32 = 140; -pub const _NLSCMPERROR: u32 = 2147483647; -pub type va_list = *mut ::std::os::raw::c_char; -unsafe extern "C" { - pub fn __va_start(arg1: *mut *mut ::std::os::raw::c_char, ...); -} -pub type __vcrt_bool = bool; -pub type wchar_t = ::std::os::raw::c_ushort; -unsafe extern "C" { - pub fn __security_init_cookie(); -} -unsafe extern "C" { - pub fn __security_check_cookie(_StackCookie: usize); -} -unsafe extern "C" { - pub fn __report_gsfailure(_StackCookie: usize) -> !; -} -unsafe extern "C" { - pub static mut __security_cookie: usize; -} -pub type __crt_bool = bool; -unsafe extern "C" { - pub fn _invalid_parameter_noinfo(); -} -unsafe extern "C" { - pub fn _invalid_parameter_noinfo_noreturn() -> !; -} -unsafe extern "C" { - pub fn _invoke_watson( - _Expression: *const wchar_t, - _FunctionName: *const wchar_t, - _FileName: *const wchar_t, - _LineNo: ::std::os::raw::c_uint, - _Reserved: usize, - ) -> !; +pub const false_: u32 = 0; +pub const __WORDSIZE: u32 = 64; +pub const __has_safe_buffers: u32 = 1; +pub const __DARWIN_ONLY_64_BIT_INO_T: u32 = 1; +pub const __DARWIN_ONLY_UNIX_CONFORMANCE: u32 = 1; +pub const __DARWIN_ONLY_VERS_1050: u32 = 1; +pub const __DARWIN_UNIX03: u32 = 1; +pub const __DARWIN_64_BIT_INO_T: u32 = 1; +pub const __DARWIN_VERS_1050: u32 = 1; +pub const __DARWIN_NON_CANCELABLE: u32 = 0; +pub const __DARWIN_SUF_EXTSN: &[u8; 14] = b"$DARWIN_EXTSN\0"; +pub const __DARWIN_C_ANSI: u32 = 4096; +pub const __DARWIN_C_FULL: u32 = 900000; +pub const __DARWIN_C_LEVEL: u32 = 900000; +pub const __STDC_WANT_LIB_EXT1__: u32 = 1; +pub const __DARWIN_NO_LONG_LONG: u32 = 0; +pub const _DARWIN_FEATURE_64_BIT_INODE: u32 = 1; +pub const _DARWIN_FEATURE_ONLY_64_BIT_INODE: u32 = 1; +pub const _DARWIN_FEATURE_ONLY_VERS_1050: u32 = 1; +pub const _DARWIN_FEATURE_ONLY_UNIX_CONFORMANCE: u32 = 1; +pub const _DARWIN_FEATURE_UNIX_CONFORMANCE: u32 = 3; +pub const __has_ptrcheck: u32 = 0; +pub const USE_CLANG_TYPES: u32 = 0; +pub const __PTHREAD_SIZE__: u32 = 8176; +pub const __PTHREAD_ATTR_SIZE__: u32 = 56; +pub const __PTHREAD_MUTEXATTR_SIZE__: u32 = 8; +pub const __PTHREAD_MUTEX_SIZE__: u32 = 56; +pub const __PTHREAD_CONDATTR_SIZE__: u32 = 8; +pub const __PTHREAD_COND_SIZE__: u32 = 40; +pub const __PTHREAD_ONCE_SIZE__: u32 = 8; +pub const __PTHREAD_RWLOCK_SIZE__: u32 = 192; +pub const __PTHREAD_RWLOCKATTR_SIZE__: u32 = 16; +pub const INT8_MAX: u32 = 127; +pub const INT16_MAX: u32 = 32767; +pub const INT32_MAX: u32 = 2147483647; +pub const INT64_MAX: u64 = 9223372036854775807; +pub const INT8_MIN: i32 = -128; +pub const INT16_MIN: i32 = -32768; +pub const INT32_MIN: i32 = -2147483648; +pub const INT64_MIN: i64 = -9223372036854775808; +pub const UINT8_MAX: u32 = 255; +pub const UINT16_MAX: u32 = 65535; +pub const UINT32_MAX: u32 = 4294967295; +pub const UINT64_MAX: i32 = -1; +pub const INT_LEAST8_MIN: i32 = -128; +pub const INT_LEAST16_MIN: i32 = -32768; +pub const INT_LEAST32_MIN: i32 = -2147483648; +pub const INT_LEAST64_MIN: i64 = -9223372036854775808; +pub const INT_LEAST8_MAX: u32 = 127; +pub const INT_LEAST16_MAX: u32 = 32767; +pub const INT_LEAST32_MAX: u32 = 2147483647; +pub const INT_LEAST64_MAX: u64 = 9223372036854775807; +pub const UINT_LEAST8_MAX: u32 = 255; +pub const UINT_LEAST16_MAX: u32 = 65535; +pub const UINT_LEAST32_MAX: u32 = 4294967295; +pub const UINT_LEAST64_MAX: i32 = -1; +pub const INT_FAST8_MIN: i32 = -128; +pub const INT_FAST16_MIN: i32 = -32768; +pub const INT_FAST32_MIN: i32 = -2147483648; +pub const INT_FAST64_MIN: i64 = -9223372036854775808; +pub const INT_FAST8_MAX: u32 = 127; +pub const INT_FAST16_MAX: u32 = 32767; +pub const INT_FAST32_MAX: u32 = 2147483647; +pub const INT_FAST64_MAX: u64 = 9223372036854775807; +pub const UINT_FAST8_MAX: u32 = 255; +pub const UINT_FAST16_MAX: u32 = 65535; +pub const UINT_FAST32_MAX: u32 = 4294967295; +pub const UINT_FAST64_MAX: i32 = -1; +pub const INTPTR_MAX: u64 = 9223372036854775807; +pub const INTPTR_MIN: i64 = -9223372036854775808; +pub const UINTPTR_MAX: i32 = -1; +pub const SIZE_MAX: i32 = -1; +pub const RSIZE_MAX: i32 = -1; +pub const WINT_MIN: i32 = -2147483648; +pub const WINT_MAX: u32 = 2147483647; +pub const SIG_ATOMIC_MIN: i32 = -2147483648; +pub const SIG_ATOMIC_MAX: u32 = 2147483647; +pub const __DARWIN_WCHAR_MIN: i32 = -2147483648; +pub const _FORTIFY_SOURCE: u32 = 2; +pub const __API_TO_BE_DEPRECATED: u32 = 100000; +pub const __API_TO_BE_DEPRECATED_MACOS: u32 = 100000; +pub const __API_TO_BE_DEPRECATED_IOS: u32 = 100000; +pub const __API_TO_BE_DEPRECATED_MACCATALYST: u32 = 100000; +pub const __API_TO_BE_DEPRECATED_WATCHOS: u32 = 100000; +pub const __API_TO_BE_DEPRECATED_TVOS: u32 = 100000; +pub const __API_TO_BE_DEPRECATED_DRIVERKIT: u32 = 100000; +pub const __API_TO_BE_DEPRECATED_VISIONOS: u32 = 100000; +pub const __MAC_10_0: u32 = 1000; +pub const __MAC_10_1: u32 = 1010; +pub const __MAC_10_2: u32 = 1020; +pub const __MAC_10_3: u32 = 1030; +pub const __MAC_10_4: u32 = 1040; +pub const __MAC_10_5: u32 = 1050; +pub const __MAC_10_6: u32 = 1060; +pub const __MAC_10_7: u32 = 1070; +pub const __MAC_10_8: u32 = 1080; +pub const __MAC_10_9: u32 = 1090; +pub const __MAC_10_10: u32 = 101000; +pub const __MAC_10_10_2: u32 = 101002; +pub const __MAC_10_10_3: u32 = 101003; +pub const __MAC_10_11: u32 = 101100; +pub const __MAC_10_11_2: u32 = 101102; +pub const __MAC_10_11_3: u32 = 101103; +pub const __MAC_10_11_4: u32 = 101104; +pub const __MAC_10_12: u32 = 101200; +pub const __MAC_10_12_1: u32 = 101201; +pub const __MAC_10_12_2: u32 = 101202; +pub const __MAC_10_12_4: u32 = 101204; +pub const __MAC_10_13: u32 = 101300; +pub const __MAC_10_13_1: u32 = 101301; +pub const __MAC_10_13_2: u32 = 101302; +pub const __MAC_10_13_4: u32 = 101304; +pub const __MAC_10_14: u32 = 101400; +pub const __MAC_10_14_1: u32 = 101401; +pub const __MAC_10_14_4: u32 = 101404; +pub const __MAC_10_14_5: u32 = 101405; +pub const __MAC_10_14_6: u32 = 101406; +pub const __MAC_10_15: u32 = 101500; +pub const __MAC_10_15_1: u32 = 101501; +pub const __MAC_10_15_4: u32 = 101504; +pub const __MAC_10_16: u32 = 101600; +pub const __MAC_11_0: u32 = 110000; +pub const __MAC_11_1: u32 = 110100; +pub const __MAC_11_3: u32 = 110300; +pub const __MAC_11_4: u32 = 110400; +pub const __MAC_11_5: u32 = 110500; +pub const __MAC_11_6: u32 = 110600; +pub const __MAC_12_0: u32 = 120000; +pub const __MAC_12_1: u32 = 120100; +pub const __MAC_12_2: u32 = 120200; +pub const __MAC_12_3: u32 = 120300; +pub const __MAC_12_4: u32 = 120400; +pub const __MAC_12_5: u32 = 120500; +pub const __MAC_12_6: u32 = 120600; +pub const __MAC_12_7: u32 = 120700; +pub const __MAC_13_0: u32 = 130000; +pub const __MAC_13_1: u32 = 130100; +pub const __MAC_13_2: u32 = 130200; +pub const __MAC_13_3: u32 = 130300; +pub const __MAC_13_4: u32 = 130400; +pub const __MAC_13_5: u32 = 130500; +pub const __MAC_13_6: u32 = 130600; +pub const __MAC_14_0: u32 = 140000; +pub const __MAC_14_1: u32 = 140100; +pub const __MAC_14_2: u32 = 140200; +pub const __MAC_14_3: u32 = 140300; +pub const __MAC_14_4: u32 = 140400; +pub const __MAC_14_5: u32 = 140500; +pub const __MAC_15_0: u32 = 150000; +pub const __MAC_15_1: u32 = 150100; +pub const __MAC_15_2: u32 = 150200; +pub const __IPHONE_2_0: u32 = 20000; +pub const __IPHONE_2_1: u32 = 20100; +pub const __IPHONE_2_2: u32 = 20200; +pub const __IPHONE_3_0: u32 = 30000; +pub const __IPHONE_3_1: u32 = 30100; +pub const __IPHONE_3_2: u32 = 30200; +pub const __IPHONE_4_0: u32 = 40000; +pub const __IPHONE_4_1: u32 = 40100; +pub const __IPHONE_4_2: u32 = 40200; +pub const __IPHONE_4_3: u32 = 40300; +pub const __IPHONE_5_0: u32 = 50000; +pub const __IPHONE_5_1: u32 = 50100; +pub const __IPHONE_6_0: u32 = 60000; +pub const __IPHONE_6_1: u32 = 60100; +pub const __IPHONE_7_0: u32 = 70000; +pub const __IPHONE_7_1: u32 = 70100; +pub const __IPHONE_8_0: u32 = 80000; +pub const __IPHONE_8_1: u32 = 80100; +pub const __IPHONE_8_2: u32 = 80200; +pub const __IPHONE_8_3: u32 = 80300; +pub const __IPHONE_8_4: u32 = 80400; +pub const __IPHONE_9_0: u32 = 90000; +pub const __IPHONE_9_1: u32 = 90100; +pub const __IPHONE_9_2: u32 = 90200; +pub const __IPHONE_9_3: u32 = 90300; +pub const __IPHONE_10_0: u32 = 100000; +pub const __IPHONE_10_1: u32 = 100100; +pub const __IPHONE_10_2: u32 = 100200; +pub const __IPHONE_10_3: u32 = 100300; +pub const __IPHONE_11_0: u32 = 110000; +pub const __IPHONE_11_1: u32 = 110100; +pub const __IPHONE_11_2: u32 = 110200; +pub const __IPHONE_11_3: u32 = 110300; +pub const __IPHONE_11_4: u32 = 110400; +pub const __IPHONE_12_0: u32 = 120000; +pub const __IPHONE_12_1: u32 = 120100; +pub const __IPHONE_12_2: u32 = 120200; +pub const __IPHONE_12_3: u32 = 120300; +pub const __IPHONE_12_4: u32 = 120400; +pub const __IPHONE_13_0: u32 = 130000; +pub const __IPHONE_13_1: u32 = 130100; +pub const __IPHONE_13_2: u32 = 130200; +pub const __IPHONE_13_3: u32 = 130300; +pub const __IPHONE_13_4: u32 = 130400; +pub const __IPHONE_13_5: u32 = 130500; +pub const __IPHONE_13_6: u32 = 130600; +pub const __IPHONE_13_7: u32 = 130700; +pub const __IPHONE_14_0: u32 = 140000; +pub const __IPHONE_14_1: u32 = 140100; +pub const __IPHONE_14_2: u32 = 140200; +pub const __IPHONE_14_3: u32 = 140300; +pub const __IPHONE_14_5: u32 = 140500; +pub const __IPHONE_14_4: u32 = 140400; +pub const __IPHONE_14_6: u32 = 140600; +pub const __IPHONE_14_7: u32 = 140700; +pub const __IPHONE_14_8: u32 = 140800; +pub const __IPHONE_15_0: u32 = 150000; +pub const __IPHONE_15_1: u32 = 150100; +pub const __IPHONE_15_2: u32 = 150200; +pub const __IPHONE_15_3: u32 = 150300; +pub const __IPHONE_15_4: u32 = 150400; +pub const __IPHONE_15_5: u32 = 150500; +pub const __IPHONE_15_6: u32 = 150600; +pub const __IPHONE_15_7: u32 = 150700; +pub const __IPHONE_15_8: u32 = 150800; +pub const __IPHONE_16_0: u32 = 160000; +pub const __IPHONE_16_1: u32 = 160100; +pub const __IPHONE_16_2: u32 = 160200; +pub const __IPHONE_16_3: u32 = 160300; +pub const __IPHONE_16_4: u32 = 160400; +pub const __IPHONE_16_5: u32 = 160500; +pub const __IPHONE_16_6: u32 = 160600; +pub const __IPHONE_16_7: u32 = 160700; +pub const __IPHONE_17_0: u32 = 170000; +pub const __IPHONE_17_1: u32 = 170100; +pub const __IPHONE_17_2: u32 = 170200; +pub const __IPHONE_17_3: u32 = 170300; +pub const __IPHONE_17_4: u32 = 170400; +pub const __IPHONE_17_5: u32 = 170500; +pub const __IPHONE_18_0: u32 = 180000; +pub const __IPHONE_18_1: u32 = 180100; +pub const __IPHONE_18_2: u32 = 180200; +pub const __WATCHOS_1_0: u32 = 10000; +pub const __WATCHOS_2_0: u32 = 20000; +pub const __WATCHOS_2_1: u32 = 20100; +pub const __WATCHOS_2_2: u32 = 20200; +pub const __WATCHOS_3_0: u32 = 30000; +pub const __WATCHOS_3_1: u32 = 30100; +pub const __WATCHOS_3_1_1: u32 = 30101; +pub const __WATCHOS_3_2: u32 = 30200; +pub const __WATCHOS_4_0: u32 = 40000; +pub const __WATCHOS_4_1: u32 = 40100; +pub const __WATCHOS_4_2: u32 = 40200; +pub const __WATCHOS_4_3: u32 = 40300; +pub const __WATCHOS_5_0: u32 = 50000; +pub const __WATCHOS_5_1: u32 = 50100; +pub const __WATCHOS_5_2: u32 = 50200; +pub const __WATCHOS_5_3: u32 = 50300; +pub const __WATCHOS_6_0: u32 = 60000; +pub const __WATCHOS_6_1: u32 = 60100; +pub const __WATCHOS_6_2: u32 = 60200; +pub const __WATCHOS_7_0: u32 = 70000; +pub const __WATCHOS_7_1: u32 = 70100; +pub const __WATCHOS_7_2: u32 = 70200; +pub const __WATCHOS_7_3: u32 = 70300; +pub const __WATCHOS_7_4: u32 = 70400; +pub const __WATCHOS_7_5: u32 = 70500; +pub const __WATCHOS_7_6: u32 = 70600; +pub const __WATCHOS_8_0: u32 = 80000; +pub const __WATCHOS_8_1: u32 = 80100; +pub const __WATCHOS_8_3: u32 = 80300; +pub const __WATCHOS_8_4: u32 = 80400; +pub const __WATCHOS_8_5: u32 = 80500; +pub const __WATCHOS_8_6: u32 = 80600; +pub const __WATCHOS_8_7: u32 = 80700; +pub const __WATCHOS_8_8: u32 = 80800; +pub const __WATCHOS_9_0: u32 = 90000; +pub const __WATCHOS_9_1: u32 = 90100; +pub const __WATCHOS_9_2: u32 = 90200; +pub const __WATCHOS_9_3: u32 = 90300; +pub const __WATCHOS_9_4: u32 = 90400; +pub const __WATCHOS_9_5: u32 = 90500; +pub const __WATCHOS_9_6: u32 = 90600; +pub const __WATCHOS_10_0: u32 = 100000; +pub const __WATCHOS_10_1: u32 = 100100; +pub const __WATCHOS_10_2: u32 = 100200; +pub const __WATCHOS_10_3: u32 = 100300; +pub const __WATCHOS_10_4: u32 = 100400; +pub const __WATCHOS_10_5: u32 = 100500; +pub const __WATCHOS_11_0: u32 = 110000; +pub const __WATCHOS_11_1: u32 = 110100; +pub const __WATCHOS_11_2: u32 = 110200; +pub const __TVOS_9_0: u32 = 90000; +pub const __TVOS_9_1: u32 = 90100; +pub const __TVOS_9_2: u32 = 90200; +pub const __TVOS_10_0: u32 = 100000; +pub const __TVOS_10_0_1: u32 = 100001; +pub const __TVOS_10_1: u32 = 100100; +pub const __TVOS_10_2: u32 = 100200; +pub const __TVOS_11_0: u32 = 110000; +pub const __TVOS_11_1: u32 = 110100; +pub const __TVOS_11_2: u32 = 110200; +pub const __TVOS_11_3: u32 = 110300; +pub const __TVOS_11_4: u32 = 110400; +pub const __TVOS_12_0: u32 = 120000; +pub const __TVOS_12_1: u32 = 120100; +pub const __TVOS_12_2: u32 = 120200; +pub const __TVOS_12_3: u32 = 120300; +pub const __TVOS_12_4: u32 = 120400; +pub const __TVOS_13_0: u32 = 130000; +pub const __TVOS_13_2: u32 = 130200; +pub const __TVOS_13_3: u32 = 130300; +pub const __TVOS_13_4: u32 = 130400; +pub const __TVOS_14_0: u32 = 140000; +pub const __TVOS_14_1: u32 = 140100; +pub const __TVOS_14_2: u32 = 140200; +pub const __TVOS_14_3: u32 = 140300; +pub const __TVOS_14_5: u32 = 140500; +pub const __TVOS_14_6: u32 = 140600; +pub const __TVOS_14_7: u32 = 140700; +pub const __TVOS_15_0: u32 = 150000; +pub const __TVOS_15_1: u32 = 150100; +pub const __TVOS_15_2: u32 = 150200; +pub const __TVOS_15_3: u32 = 150300; +pub const __TVOS_15_4: u32 = 150400; +pub const __TVOS_15_5: u32 = 150500; +pub const __TVOS_15_6: u32 = 150600; +pub const __TVOS_16_0: u32 = 160000; +pub const __TVOS_16_1: u32 = 160100; +pub const __TVOS_16_2: u32 = 160200; +pub const __TVOS_16_3: u32 = 160300; +pub const __TVOS_16_4: u32 = 160400; +pub const __TVOS_16_5: u32 = 160500; +pub const __TVOS_16_6: u32 = 160600; +pub const __TVOS_17_0: u32 = 170000; +pub const __TVOS_17_1: u32 = 170100; +pub const __TVOS_17_2: u32 = 170200; +pub const __TVOS_17_3: u32 = 170300; +pub const __TVOS_17_4: u32 = 170400; +pub const __TVOS_17_5: u32 = 170500; +pub const __TVOS_18_0: u32 = 180000; +pub const __TVOS_18_1: u32 = 180100; +pub const __TVOS_18_2: u32 = 180200; +pub const __BRIDGEOS_2_0: u32 = 20000; +pub const __BRIDGEOS_3_0: u32 = 30000; +pub const __BRIDGEOS_3_1: u32 = 30100; +pub const __BRIDGEOS_3_4: u32 = 30400; +pub const __BRIDGEOS_4_0: u32 = 40000; +pub const __BRIDGEOS_4_1: u32 = 40100; +pub const __BRIDGEOS_5_0: u32 = 50000; +pub const __BRIDGEOS_5_1: u32 = 50100; +pub const __BRIDGEOS_5_3: u32 = 50300; +pub const __BRIDGEOS_6_0: u32 = 60000; +pub const __BRIDGEOS_6_2: u32 = 60200; +pub const __BRIDGEOS_6_4: u32 = 60400; +pub const __BRIDGEOS_6_5: u32 = 60500; +pub const __BRIDGEOS_6_6: u32 = 60600; +pub const __BRIDGEOS_7_0: u32 = 70000; +pub const __BRIDGEOS_7_1: u32 = 70100; +pub const __BRIDGEOS_7_2: u32 = 70200; +pub const __BRIDGEOS_7_3: u32 = 70300; +pub const __BRIDGEOS_7_4: u32 = 70400; +pub const __BRIDGEOS_7_6: u32 = 70600; +pub const __BRIDGEOS_8_0: u32 = 80000; +pub const __BRIDGEOS_8_1: u32 = 80100; +pub const __BRIDGEOS_8_2: u32 = 80200; +pub const __BRIDGEOS_8_3: u32 = 80300; +pub const __BRIDGEOS_8_4: u32 = 80400; +pub const __BRIDGEOS_8_5: u32 = 80500; +pub const __BRIDGEOS_9_0: u32 = 90000; +pub const __BRIDGEOS_9_1: u32 = 90100; +pub const __BRIDGEOS_9_2: u32 = 90200; +pub const __DRIVERKIT_19_0: u32 = 190000; +pub const __DRIVERKIT_20_0: u32 = 200000; +pub const __DRIVERKIT_21_0: u32 = 210000; +pub const __DRIVERKIT_22_0: u32 = 220000; +pub const __DRIVERKIT_22_4: u32 = 220400; +pub const __DRIVERKIT_22_5: u32 = 220500; +pub const __DRIVERKIT_22_6: u32 = 220600; +pub const __DRIVERKIT_23_0: u32 = 230000; +pub const __DRIVERKIT_23_1: u32 = 230100; +pub const __DRIVERKIT_23_2: u32 = 230200; +pub const __DRIVERKIT_23_3: u32 = 230300; +pub const __DRIVERKIT_23_4: u32 = 230400; +pub const __DRIVERKIT_23_5: u32 = 230500; +pub const __DRIVERKIT_24_0: u32 = 240000; +pub const __DRIVERKIT_24_1: u32 = 240100; +pub const __DRIVERKIT_24_2: u32 = 240200; +pub const __VISIONOS_1_0: u32 = 10000; +pub const __VISIONOS_1_1: u32 = 10100; +pub const __VISIONOS_1_2: u32 = 10200; +pub const __VISIONOS_2_0: u32 = 20000; +pub const __VISIONOS_2_1: u32 = 20100; +pub const __VISIONOS_2_2: u32 = 20200; +pub const MAC_OS_X_VERSION_10_0: u32 = 1000; +pub const MAC_OS_X_VERSION_10_1: u32 = 1010; +pub const MAC_OS_X_VERSION_10_2: u32 = 1020; +pub const MAC_OS_X_VERSION_10_3: u32 = 1030; +pub const MAC_OS_X_VERSION_10_4: u32 = 1040; +pub const MAC_OS_X_VERSION_10_5: u32 = 1050; +pub const MAC_OS_X_VERSION_10_6: u32 = 1060; +pub const MAC_OS_X_VERSION_10_7: u32 = 1070; +pub const MAC_OS_X_VERSION_10_8: u32 = 1080; +pub const MAC_OS_X_VERSION_10_9: u32 = 1090; +pub const MAC_OS_X_VERSION_10_10: u32 = 101000; +pub const MAC_OS_X_VERSION_10_10_2: u32 = 101002; +pub const MAC_OS_X_VERSION_10_10_3: u32 = 101003; +pub const MAC_OS_X_VERSION_10_11: u32 = 101100; +pub const MAC_OS_X_VERSION_10_11_2: u32 = 101102; +pub const MAC_OS_X_VERSION_10_11_3: u32 = 101103; +pub const MAC_OS_X_VERSION_10_11_4: u32 = 101104; +pub const MAC_OS_X_VERSION_10_12: u32 = 101200; +pub const MAC_OS_X_VERSION_10_12_1: u32 = 101201; +pub const MAC_OS_X_VERSION_10_12_2: u32 = 101202; +pub const MAC_OS_X_VERSION_10_12_4: u32 = 101204; +pub const MAC_OS_X_VERSION_10_13: u32 = 101300; +pub const MAC_OS_X_VERSION_10_13_1: u32 = 101301; +pub const MAC_OS_X_VERSION_10_13_2: u32 = 101302; +pub const MAC_OS_X_VERSION_10_13_4: u32 = 101304; +pub const MAC_OS_X_VERSION_10_14: u32 = 101400; +pub const MAC_OS_X_VERSION_10_14_1: u32 = 101401; +pub const MAC_OS_X_VERSION_10_14_4: u32 = 101404; +pub const MAC_OS_X_VERSION_10_14_5: u32 = 101405; +pub const MAC_OS_X_VERSION_10_14_6: u32 = 101406; +pub const MAC_OS_X_VERSION_10_15: u32 = 101500; +pub const MAC_OS_X_VERSION_10_15_1: u32 = 101501; +pub const MAC_OS_X_VERSION_10_15_4: u32 = 101504; +pub const MAC_OS_X_VERSION_10_16: u32 = 101600; +pub const MAC_OS_VERSION_11_0: u32 = 110000; +pub const MAC_OS_VERSION_11_1: u32 = 110100; +pub const MAC_OS_VERSION_11_3: u32 = 110300; +pub const MAC_OS_VERSION_11_4: u32 = 110400; +pub const MAC_OS_VERSION_11_5: u32 = 110500; +pub const MAC_OS_VERSION_11_6: u32 = 110600; +pub const MAC_OS_VERSION_12_0: u32 = 120000; +pub const MAC_OS_VERSION_12_1: u32 = 120100; +pub const MAC_OS_VERSION_12_2: u32 = 120200; +pub const MAC_OS_VERSION_12_3: u32 = 120300; +pub const MAC_OS_VERSION_12_4: u32 = 120400; +pub const MAC_OS_VERSION_12_5: u32 = 120500; +pub const MAC_OS_VERSION_12_6: u32 = 120600; +pub const MAC_OS_VERSION_12_7: u32 = 120700; +pub const MAC_OS_VERSION_13_0: u32 = 130000; +pub const MAC_OS_VERSION_13_1: u32 = 130100; +pub const MAC_OS_VERSION_13_2: u32 = 130200; +pub const MAC_OS_VERSION_13_3: u32 = 130300; +pub const MAC_OS_VERSION_13_4: u32 = 130400; +pub const MAC_OS_VERSION_13_5: u32 = 130500; +pub const MAC_OS_VERSION_13_6: u32 = 130600; +pub const MAC_OS_VERSION_14_0: u32 = 140000; +pub const MAC_OS_VERSION_14_1: u32 = 140100; +pub const MAC_OS_VERSION_14_2: u32 = 140200; +pub const MAC_OS_VERSION_14_3: u32 = 140300; +pub const MAC_OS_VERSION_14_4: u32 = 140400; +pub const MAC_OS_VERSION_14_5: u32 = 140500; +pub const MAC_OS_VERSION_15_0: u32 = 150000; +pub const MAC_OS_VERSION_15_1: u32 = 150100; +pub const MAC_OS_VERSION_15_2: u32 = 150200; +pub const __MAC_OS_X_VERSION_MAX_ALLOWED: u32 = 150200; +pub const __ENABLE_LEGACY_MAC_AVAILABILITY: u32 = 1; +pub const USE_CLANG_STDDEF: u32 = 0; +pub const _USE_FORTIFY_LEVEL: u32 = 2; +pub const __HAS_FIXED_CHK_PROTOTYPES: u32 = 1; +pub type wchar_t = ::std::os::raw::c_int; +pub type max_align_t = f64; +pub type int_least8_t = i8; +pub type int_least16_t = i16; +pub type int_least32_t = i32; +pub type int_least64_t = i64; +pub type uint_least8_t = u8; +pub type uint_least16_t = u16; +pub type uint_least32_t = u32; +pub type uint_least64_t = u64; +pub type int_fast8_t = i8; +pub type int_fast16_t = i16; +pub type int_fast32_t = i32; +pub type int_fast64_t = i64; +pub type uint_fast8_t = u8; +pub type uint_fast16_t = u16; +pub type uint_fast32_t = u32; +pub type uint_fast64_t = u64; +pub type __int8_t = ::std::os::raw::c_schar; +pub type __uint8_t = ::std::os::raw::c_uchar; +pub type __int16_t = ::std::os::raw::c_short; +pub type __uint16_t = ::std::os::raw::c_ushort; +pub type __int32_t = ::std::os::raw::c_int; +pub type __uint32_t = ::std::os::raw::c_uint; +pub type __int64_t = ::std::os::raw::c_longlong; +pub type __uint64_t = ::std::os::raw::c_ulonglong; +pub type __darwin_intptr_t = ::std::os::raw::c_long; +pub type __darwin_natural_t = ::std::os::raw::c_uint; +pub type __darwin_ct_rune_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Copy, Clone)] +pub union __mbstate_t { + pub __mbstate8: [::std::os::raw::c_char; 128usize], + pub _mbstateL: ::std::os::raw::c_longlong, } -pub type errno_t = ::std::os::raw::c_int; -pub type wint_t = ::std::os::raw::c_ushort; -pub type wctype_t = ::std::os::raw::c_ushort; -pub type __time32_t = ::std::os::raw::c_long; -pub type __time64_t = ::std::os::raw::c_longlong; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of __mbstate_t"][::std::mem::size_of::<__mbstate_t>() - 128usize]; + ["Alignment of __mbstate_t"][::std::mem::align_of::<__mbstate_t>() - 8usize]; + ["Offset of field: __mbstate_t::__mbstate8"] + [::std::mem::offset_of!(__mbstate_t, __mbstate8) - 0usize]; + ["Offset of field: __mbstate_t::_mbstateL"] + [::std::mem::offset_of!(__mbstate_t, _mbstateL) - 0usize]; +}; +pub type __darwin_mbstate_t = __mbstate_t; +pub type __darwin_ptrdiff_t = ::std::os::raw::c_long; +pub type __darwin_size_t = ::std::os::raw::c_ulong; +pub type __darwin_va_list = __builtin_va_list; +pub type __darwin_wchar_t = ::std::os::raw::c_int; +pub type __darwin_rune_t = __darwin_wchar_t; +pub type __darwin_wint_t = ::std::os::raw::c_int; +pub type __darwin_clock_t = ::std::os::raw::c_ulong; +pub type __darwin_socklen_t = __uint32_t; +pub type __darwin_ssize_t = ::std::os::raw::c_long; +pub type __darwin_time_t = ::std::os::raw::c_long; +pub type __darwin_blkcnt_t = __int64_t; +pub type __darwin_blksize_t = __int32_t; +pub type __darwin_dev_t = __int32_t; +pub type __darwin_fsblkcnt_t = ::std::os::raw::c_uint; +pub type __darwin_fsfilcnt_t = ::std::os::raw::c_uint; +pub type __darwin_gid_t = __uint32_t; +pub type __darwin_id_t = __uint32_t; +pub type __darwin_ino64_t = __uint64_t; +pub type __darwin_ino_t = __darwin_ino64_t; +pub type __darwin_mach_port_name_t = __darwin_natural_t; +pub type __darwin_mach_port_t = __darwin_mach_port_name_t; +pub type __darwin_mode_t = __uint16_t; +pub type __darwin_off_t = __int64_t; +pub type __darwin_pid_t = __int32_t; +pub type __darwin_sigset_t = __uint32_t; +pub type __darwin_suseconds_t = __int32_t; +pub type __darwin_uid_t = __uint32_t; +pub type __darwin_useconds_t = __uint32_t; +pub type __darwin_uuid_t = [::std::os::raw::c_uchar; 16usize]; +pub type __darwin_uuid_string_t = [::std::os::raw::c_char; 37usize]; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct __crt_locale_data_public { - pub _locale_pctype: *const ::std::os::raw::c_ushort, - pub _locale_mb_cur_max: ::std::os::raw::c_int, - pub _locale_lc_codepage: ::std::os::raw::c_uint, +pub struct __darwin_pthread_handler_rec { + pub __routine: ::std::option::Option, + pub __arg: *mut ::std::os::raw::c_void, + pub __next: *mut __darwin_pthread_handler_rec, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] const _: () = { - ["Size of __crt_locale_data_public"] - [::std::mem::size_of::<__crt_locale_data_public>() - 16usize]; - ["Alignment of __crt_locale_data_public"] - [::std::mem::align_of::<__crt_locale_data_public>() - 8usize]; - ["Offset of field: __crt_locale_data_public::_locale_pctype"] - [::std::mem::offset_of!(__crt_locale_data_public, _locale_pctype) - 0usize]; - ["Offset of field: __crt_locale_data_public::_locale_mb_cur_max"] - [::std::mem::offset_of!(__crt_locale_data_public, _locale_mb_cur_max) - 8usize]; - ["Offset of field: __crt_locale_data_public::_locale_lc_codepage"] - [::std::mem::offset_of!(__crt_locale_data_public, _locale_lc_codepage) - 12usize]; + ["Size of __darwin_pthread_handler_rec"] + [::std::mem::size_of::<__darwin_pthread_handler_rec>() - 24usize]; + ["Alignment of __darwin_pthread_handler_rec"] + [::std::mem::align_of::<__darwin_pthread_handler_rec>() - 8usize]; + ["Offset of field: __darwin_pthread_handler_rec::__routine"] + [::std::mem::offset_of!(__darwin_pthread_handler_rec, __routine) - 0usize]; + ["Offset of field: __darwin_pthread_handler_rec::__arg"] + [::std::mem::offset_of!(__darwin_pthread_handler_rec, __arg) - 8usize]; + ["Offset of field: __darwin_pthread_handler_rec::__next"] + [::std::mem::offset_of!(__darwin_pthread_handler_rec, __next) - 16usize]; }; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct __crt_locale_pointers { - pub locinfo: *mut __crt_locale_data, - pub mbcinfo: *mut __crt_multibyte_data, +pub struct _opaque_pthread_attr_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 56usize], } #[allow(clippy::unnecessary_operation, clippy::identity_op)] const _: () = { - ["Size of __crt_locale_pointers"][::std::mem::size_of::<__crt_locale_pointers>() - 16usize]; - ["Alignment of __crt_locale_pointers"] - [::std::mem::align_of::<__crt_locale_pointers>() - 8usize]; - ["Offset of field: __crt_locale_pointers::locinfo"] - [::std::mem::offset_of!(__crt_locale_pointers, locinfo) - 0usize]; - ["Offset of field: __crt_locale_pointers::mbcinfo"] - [::std::mem::offset_of!(__crt_locale_pointers, mbcinfo) - 8usize]; + ["Size of _opaque_pthread_attr_t"][::std::mem::size_of::<_opaque_pthread_attr_t>() - 64usize]; + ["Alignment of _opaque_pthread_attr_t"] + [::std::mem::align_of::<_opaque_pthread_attr_t>() - 8usize]; + ["Offset of field: _opaque_pthread_attr_t::__sig"] + [::std::mem::offset_of!(_opaque_pthread_attr_t, __sig) - 0usize]; + ["Offset of field: _opaque_pthread_attr_t::__opaque"] + [::std::mem::offset_of!(_opaque_pthread_attr_t, __opaque) - 8usize]; }; -pub type _locale_t = *mut __crt_locale_pointers; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct _Mbstatet { - pub _Wchar: ::std::os::raw::c_ulong, - pub _Byte: ::std::os::raw::c_ushort, - pub _State: ::std::os::raw::c_ushort, +pub struct _opaque_pthread_cond_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 40usize], } #[allow(clippy::unnecessary_operation, clippy::identity_op)] const _: () = { - ["Size of _Mbstatet"][::std::mem::size_of::<_Mbstatet>() - 8usize]; - ["Alignment of _Mbstatet"][::std::mem::align_of::<_Mbstatet>() - 4usize]; - ["Offset of field: _Mbstatet::_Wchar"][::std::mem::offset_of!(_Mbstatet, _Wchar) - 0usize]; - ["Offset of field: _Mbstatet::_Byte"][::std::mem::offset_of!(_Mbstatet, _Byte) - 4usize]; - ["Offset of field: _Mbstatet::_State"][::std::mem::offset_of!(_Mbstatet, _State) - 6usize]; + ["Size of _opaque_pthread_cond_t"][::std::mem::size_of::<_opaque_pthread_cond_t>() - 48usize]; + ["Alignment of _opaque_pthread_cond_t"] + [::std::mem::align_of::<_opaque_pthread_cond_t>() - 8usize]; + ["Offset of field: _opaque_pthread_cond_t::__sig"] + [::std::mem::offset_of!(_opaque_pthread_cond_t, __sig) - 0usize]; + ["Offset of field: _opaque_pthread_cond_t::__opaque"] + [::std::mem::offset_of!(_opaque_pthread_cond_t, __opaque) - 8usize]; }; -pub type mbstate_t = _Mbstatet; -pub type time_t = __time64_t; -pub type rsize_t = usize; -unsafe extern "C" { - pub fn _errno() -> *mut ::std::os::raw::c_int; -} -unsafe extern "C" { - pub fn _set_errno(_Value: ::std::os::raw::c_int) -> errno_t; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _opaque_pthread_condattr_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 8usize], } -unsafe extern "C" { - pub fn _get_errno(_Value: *mut ::std::os::raw::c_int) -> errno_t; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of _opaque_pthread_condattr_t"] + [::std::mem::size_of::<_opaque_pthread_condattr_t>() - 16usize]; + ["Alignment of _opaque_pthread_condattr_t"] + [::std::mem::align_of::<_opaque_pthread_condattr_t>() - 8usize]; + ["Offset of field: _opaque_pthread_condattr_t::__sig"] + [::std::mem::offset_of!(_opaque_pthread_condattr_t, __sig) - 0usize]; + ["Offset of field: _opaque_pthread_condattr_t::__opaque"] + [::std::mem::offset_of!(_opaque_pthread_condattr_t, __opaque) - 8usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _opaque_pthread_mutex_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 56usize], } -unsafe extern "C" { - pub fn __threadid() -> ::std::os::raw::c_ulong; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of _opaque_pthread_mutex_t"][::std::mem::size_of::<_opaque_pthread_mutex_t>() - 64usize]; + ["Alignment of _opaque_pthread_mutex_t"] + [::std::mem::align_of::<_opaque_pthread_mutex_t>() - 8usize]; + ["Offset of field: _opaque_pthread_mutex_t::__sig"] + [::std::mem::offset_of!(_opaque_pthread_mutex_t, __sig) - 0usize]; + ["Offset of field: _opaque_pthread_mutex_t::__opaque"] + [::std::mem::offset_of!(_opaque_pthread_mutex_t, __opaque) - 8usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _opaque_pthread_mutexattr_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 8usize], } -unsafe extern "C" { - pub fn __threadhandle() -> usize; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of _opaque_pthread_mutexattr_t"] + [::std::mem::size_of::<_opaque_pthread_mutexattr_t>() - 16usize]; + ["Alignment of _opaque_pthread_mutexattr_t"] + [::std::mem::align_of::<_opaque_pthread_mutexattr_t>() - 8usize]; + ["Offset of field: _opaque_pthread_mutexattr_t::__sig"] + [::std::mem::offset_of!(_opaque_pthread_mutexattr_t, __sig) - 0usize]; + ["Offset of field: _opaque_pthread_mutexattr_t::__opaque"] + [::std::mem::offset_of!(_opaque_pthread_mutexattr_t, __opaque) - 8usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _opaque_pthread_once_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 8usize], } -pub type int_least8_t = ::std::os::raw::c_schar; -pub type int_least16_t = ::std::os::raw::c_short; -pub type int_least32_t = ::std::os::raw::c_int; -pub type int_least64_t = ::std::os::raw::c_longlong; -pub type uint_least8_t = ::std::os::raw::c_uchar; -pub type uint_least16_t = ::std::os::raw::c_ushort; -pub type uint_least32_t = ::std::os::raw::c_uint; -pub type uint_least64_t = ::std::os::raw::c_ulonglong; -pub type int_fast8_t = ::std::os::raw::c_schar; -pub type int_fast16_t = ::std::os::raw::c_int; -pub type int_fast32_t = ::std::os::raw::c_int; -pub type int_fast64_t = ::std::os::raw::c_longlong; -pub type uint_fast8_t = ::std::os::raw::c_uchar; -pub type uint_fast16_t = ::std::os::raw::c_uint; -pub type uint_fast32_t = ::std::os::raw::c_uint; -pub type uint_fast64_t = ::std::os::raw::c_ulonglong; -pub type intmax_t = ::std::os::raw::c_longlong; -pub type uintmax_t = ::std::os::raw::c_ulonglong; -unsafe extern "C" { - pub fn __doserrno() -> *mut ::std::os::raw::c_ulong; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of _opaque_pthread_once_t"][::std::mem::size_of::<_opaque_pthread_once_t>() - 16usize]; + ["Alignment of _opaque_pthread_once_t"] + [::std::mem::align_of::<_opaque_pthread_once_t>() - 8usize]; + ["Offset of field: _opaque_pthread_once_t::__sig"] + [::std::mem::offset_of!(_opaque_pthread_once_t, __sig) - 0usize]; + ["Offset of field: _opaque_pthread_once_t::__opaque"] + [::std::mem::offset_of!(_opaque_pthread_once_t, __opaque) - 8usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _opaque_pthread_rwlock_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 192usize], } -unsafe extern "C" { - pub fn _set_doserrno(_Value: ::std::os::raw::c_ulong) -> errno_t; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of _opaque_pthread_rwlock_t"] + [::std::mem::size_of::<_opaque_pthread_rwlock_t>() - 200usize]; + ["Alignment of _opaque_pthread_rwlock_t"] + [::std::mem::align_of::<_opaque_pthread_rwlock_t>() - 8usize]; + ["Offset of field: _opaque_pthread_rwlock_t::__sig"] + [::std::mem::offset_of!(_opaque_pthread_rwlock_t, __sig) - 0usize]; + ["Offset of field: _opaque_pthread_rwlock_t::__opaque"] + [::std::mem::offset_of!(_opaque_pthread_rwlock_t, __opaque) - 8usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _opaque_pthread_rwlockattr_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 16usize], } -unsafe extern "C" { - pub fn _get_doserrno(_Value: *mut ::std::os::raw::c_ulong) -> errno_t; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of _opaque_pthread_rwlockattr_t"] + [::std::mem::size_of::<_opaque_pthread_rwlockattr_t>() - 24usize]; + ["Alignment of _opaque_pthread_rwlockattr_t"] + [::std::mem::align_of::<_opaque_pthread_rwlockattr_t>() - 8usize]; + ["Offset of field: _opaque_pthread_rwlockattr_t::__sig"] + [::std::mem::offset_of!(_opaque_pthread_rwlockattr_t, __sig) - 0usize]; + ["Offset of field: _opaque_pthread_rwlockattr_t::__opaque"] + [::std::mem::offset_of!(_opaque_pthread_rwlockattr_t, __opaque) - 8usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _opaque_pthread_t { + pub __sig: ::std::os::raw::c_long, + pub __cleanup_stack: *mut __darwin_pthread_handler_rec, + pub __opaque: [::std::os::raw::c_char; 8176usize], } +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of _opaque_pthread_t"][::std::mem::size_of::<_opaque_pthread_t>() - 8192usize]; + ["Alignment of _opaque_pthread_t"][::std::mem::align_of::<_opaque_pthread_t>() - 8usize]; + ["Offset of field: _opaque_pthread_t::__sig"] + [::std::mem::offset_of!(_opaque_pthread_t, __sig) - 0usize]; + ["Offset of field: _opaque_pthread_t::__cleanup_stack"] + [::std::mem::offset_of!(_opaque_pthread_t, __cleanup_stack) - 8usize]; + ["Offset of field: _opaque_pthread_t::__opaque"] + [::std::mem::offset_of!(_opaque_pthread_t, __opaque) - 16usize]; +}; +pub type __darwin_pthread_attr_t = _opaque_pthread_attr_t; +pub type __darwin_pthread_cond_t = _opaque_pthread_cond_t; +pub type __darwin_pthread_condattr_t = _opaque_pthread_condattr_t; +pub type __darwin_pthread_key_t = ::std::os::raw::c_ulong; +pub type __darwin_pthread_mutex_t = _opaque_pthread_mutex_t; +pub type __darwin_pthread_mutexattr_t = _opaque_pthread_mutexattr_t; +pub type __darwin_pthread_once_t = _opaque_pthread_once_t; +pub type __darwin_pthread_rwlock_t = _opaque_pthread_rwlock_t; +pub type __darwin_pthread_rwlockattr_t = _opaque_pthread_rwlockattr_t; +pub type __darwin_pthread_t = *mut _opaque_pthread_t; +pub type intmax_t = ::std::os::raw::c_long; +pub type uintmax_t = ::std::os::raw::c_ulong; +pub type __darwin_nl_item = ::std::os::raw::c_int; +pub type __darwin_wctrans_t = ::std::os::raw::c_int; +pub type __darwin_wctype_t = __uint32_t; unsafe extern "C" { pub fn memchr( - _Buf: *const ::std::os::raw::c_void, - _Val: ::std::os::raw::c_int, - _MaxCount: ::std::os::raw::c_ulonglong, + __s: *const ::std::os::raw::c_void, + __c: ::std::os::raw::c_int, + __n: ::std::os::raw::c_ulong, ) -> *mut ::std::os::raw::c_void; } unsafe extern "C" { pub fn memcmp( - _Buf1: *const ::std::os::raw::c_void, - _Buf2: *const ::std::os::raw::c_void, - _Size: ::std::os::raw::c_ulonglong, + __s1: *const ::std::os::raw::c_void, + __s2: *const ::std::os::raw::c_void, + __n: ::std::os::raw::c_ulong, ) -> ::std::os::raw::c_int; } unsafe extern "C" { pub fn memcpy( - _Dst: *mut ::std::os::raw::c_void, - _Src: *const ::std::os::raw::c_void, - _Size: ::std::os::raw::c_ulonglong, + __dst: *mut ::std::os::raw::c_void, + __src: *const ::std::os::raw::c_void, + __n: ::std::os::raw::c_ulong, ) -> *mut ::std::os::raw::c_void; } unsafe extern "C" { pub fn memmove( - _Dst: *mut ::std::os::raw::c_void, - _Src: *const ::std::os::raw::c_void, - _Size: ::std::os::raw::c_ulonglong, + __dst: *mut ::std::os::raw::c_void, + __src: *const ::std::os::raw::c_void, + __len: ::std::os::raw::c_ulong, ) -> *mut ::std::os::raw::c_void; } unsafe extern "C" { pub fn memset( - _Dst: *mut ::std::os::raw::c_void, - _Val: ::std::os::raw::c_int, - _Size: ::std::os::raw::c_ulonglong, + __b: *mut ::std::os::raw::c_void, + __c: ::std::os::raw::c_int, + __len: ::std::os::raw::c_ulong, ) -> *mut ::std::os::raw::c_void; } unsafe extern "C" { - pub fn strchr( - _Str: *const ::std::os::raw::c_char, - _Val: ::std::os::raw::c_int, - ) -> *mut ::std::os::raw::c_char; -} -unsafe extern "C" { - pub fn strrchr( - _Str: *const ::std::os::raw::c_char, - _Ch: ::std::os::raw::c_int, + pub fn strcat( + __s1: *mut ::std::os::raw::c_char, + __s2: *const ::std::os::raw::c_char, ) -> *mut ::std::os::raw::c_char; } unsafe extern "C" { - pub fn strstr( - _Str: *const ::std::os::raw::c_char, - _SubStr: *const ::std::os::raw::c_char, + pub fn strchr( + __s: *const ::std::os::raw::c_char, + __c: ::std::os::raw::c_int, ) -> *mut ::std::os::raw::c_char; } unsafe extern "C" { - pub fn wcschr( - _Str: *const ::std::os::raw::c_ushort, - _Ch: ::std::os::raw::c_ushort, - ) -> *mut ::std::os::raw::c_ushort; -} -unsafe extern "C" { - pub fn wcsrchr(_Str: *const wchar_t, _Ch: wchar_t) -> *mut wchar_t; -} -unsafe extern "C" { - pub fn wcsstr(_Str: *const wchar_t, _SubStr: *const wchar_t) -> *mut wchar_t; -} -unsafe extern "C" { - pub fn _memicmp( - _Buf1: *const ::std::os::raw::c_void, - _Buf2: *const ::std::os::raw::c_void, - _Size: usize, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - pub fn _memicmp_l( - _Buf1: *const ::std::os::raw::c_void, - _Buf2: *const ::std::os::raw::c_void, - _Size: usize, - _Locale: _locale_t, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - pub fn memccpy( - _Dst: *mut ::std::os::raw::c_void, - _Src: *const ::std::os::raw::c_void, - _Val: ::std::os::raw::c_int, - _Size: ::std::os::raw::c_ulonglong, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - pub fn memicmp( - _Buf1: *const ::std::os::raw::c_void, - _Buf2: *const ::std::os::raw::c_void, - _Size: usize, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - pub fn wcscat_s( - _Destination: *mut wchar_t, - _SizeInWords: rsize_t, - _Source: *const wchar_t, - ) -> errno_t; -} -unsafe extern "C" { - pub fn wcscpy_s( - _Destination: *mut wchar_t, - _SizeInWords: rsize_t, - _Source: *const wchar_t, - ) -> errno_t; -} -unsafe extern "C" { - pub fn wcsncat_s( - _Destination: *mut wchar_t, - _SizeInWords: rsize_t, - _Source: *const wchar_t, - _MaxCount: rsize_t, - ) -> errno_t; -} -unsafe extern "C" { - pub fn wcsncpy_s( - _Destination: *mut wchar_t, - _SizeInWords: rsize_t, - _Source: *const wchar_t, - _MaxCount: rsize_t, - ) -> errno_t; -} -unsafe extern "C" { - pub fn wcstok_s( - _String: *mut wchar_t, - _Delimiter: *const wchar_t, - _Context: *mut *mut wchar_t, - ) -> *mut wchar_t; -} -unsafe extern "C" { - pub fn _wcsdup(_String: *const wchar_t) -> *mut wchar_t; -} -unsafe extern "C" { - pub fn wcscat(_Destination: *mut wchar_t, _Source: *const wchar_t) -> *mut wchar_t; -} -unsafe extern "C" { - pub fn wcscmp( - _String1: *const ::std::os::raw::c_ushort, - _String2: *const ::std::os::raw::c_ushort, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - pub fn wcscpy(_Destination: *mut wchar_t, _Source: *const wchar_t) -> *mut wchar_t; -} -unsafe extern "C" { - pub fn wcscspn(_String: *const wchar_t, _Control: *const wchar_t) -> usize; -} -unsafe extern "C" { - pub fn wcslen(_String: *const ::std::os::raw::c_ushort) -> ::std::os::raw::c_ulonglong; -} -unsafe extern "C" { - pub fn wcsnlen(_Source: *const wchar_t, _MaxCount: usize) -> usize; -} -unsafe extern "C" { - pub fn wcsncat( - _Destination: *mut wchar_t, - _Source: *const wchar_t, - _Count: usize, - ) -> *mut wchar_t; -} -unsafe extern "C" { - pub fn wcsncmp( - _String1: *const ::std::os::raw::c_ushort, - _String2: *const ::std::os::raw::c_ushort, - _MaxCount: ::std::os::raw::c_ulonglong, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - pub fn wcsncpy( - _Destination: *mut wchar_t, - _Source: *const wchar_t, - _Count: usize, - ) -> *mut wchar_t; -} -unsafe extern "C" { - pub fn wcspbrk(_String: *const wchar_t, _Control: *const wchar_t) -> *mut wchar_t; -} -unsafe extern "C" { - pub fn wcsspn(_String: *const wchar_t, _Control: *const wchar_t) -> usize; -} -unsafe extern "C" { - pub fn wcstok( - _String: *mut wchar_t, - _Delimiter: *const wchar_t, - _Context: *mut *mut wchar_t, - ) -> *mut wchar_t; -} -unsafe extern "C" { - pub fn _wcserror(_ErrorNumber: ::std::os::raw::c_int) -> *mut wchar_t; -} -unsafe extern "C" { - pub fn _wcserror_s( - _Buffer: *mut wchar_t, - _SizeInWords: usize, - _ErrorNumber: ::std::os::raw::c_int, - ) -> errno_t; -} -unsafe extern "C" { - pub fn __wcserror(_String: *const wchar_t) -> *mut wchar_t; -} -unsafe extern "C" { - pub fn __wcserror_s( - _Buffer: *mut wchar_t, - _SizeInWords: usize, - _ErrorMessage: *const wchar_t, - ) -> errno_t; -} -unsafe extern "C" { - pub fn _wcsicmp(_String1: *const wchar_t, _String2: *const wchar_t) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - pub fn _wcsicmp_l( - _String1: *const wchar_t, - _String2: *const wchar_t, - _Locale: _locale_t, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - pub fn _wcsnicmp( - _String1: *const wchar_t, - _String2: *const wchar_t, - _MaxCount: usize, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - pub fn _wcsnicmp_l( - _String1: *const wchar_t, - _String2: *const wchar_t, - _MaxCount: usize, - _Locale: _locale_t, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - pub fn _wcsnset_s( - _Destination: *mut wchar_t, - _SizeInWords: usize, - _Value: wchar_t, - _MaxCount: usize, - ) -> errno_t; -} -unsafe extern "C" { - pub fn _wcsnset(_String: *mut wchar_t, _Value: wchar_t, _MaxCount: usize) -> *mut wchar_t; -} -unsafe extern "C" { - pub fn _wcsrev(_String: *mut wchar_t) -> *mut wchar_t; -} -unsafe extern "C" { - pub fn _wcsset_s(_Destination: *mut wchar_t, _SizeInWords: usize, _Value: wchar_t) -> errno_t; -} -unsafe extern "C" { - pub fn _wcsset(_String: *mut wchar_t, _Value: wchar_t) -> *mut wchar_t; -} -unsafe extern "C" { - pub fn _wcslwr_s(_String: *mut wchar_t, _SizeInWords: usize) -> errno_t; -} -unsafe extern "C" { - pub fn _wcslwr(_String: *mut wchar_t) -> *mut wchar_t; -} -unsafe extern "C" { - pub fn _wcslwr_s_l(_String: *mut wchar_t, _SizeInWords: usize, _Locale: _locale_t) -> errno_t; -} -unsafe extern "C" { - pub fn _wcslwr_l(_String: *mut wchar_t, _Locale: _locale_t) -> *mut wchar_t; -} -unsafe extern "C" { - pub fn _wcsupr_s(_String: *mut wchar_t, _Size: usize) -> errno_t; -} -unsafe extern "C" { - pub fn _wcsupr(_String: *mut wchar_t) -> *mut wchar_t; -} -unsafe extern "C" { - pub fn _wcsupr_s_l(_String: *mut wchar_t, _Size: usize, _Locale: _locale_t) -> errno_t; -} -unsafe extern "C" { - pub fn _wcsupr_l(_String: *mut wchar_t, _Locale: _locale_t) -> *mut wchar_t; -} -unsafe extern "C" { - pub fn wcsxfrm(_Destination: *mut wchar_t, _Source: *const wchar_t, _MaxCount: usize) -> usize; -} -unsafe extern "C" { - pub fn _wcsxfrm_l( - _Destination: *mut wchar_t, - _Source: *const wchar_t, - _MaxCount: usize, - _Locale: _locale_t, - ) -> usize; -} -unsafe extern "C" { - pub fn wcscoll(_String1: *const wchar_t, _String2: *const wchar_t) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - pub fn _wcscoll_l( - _String1: *const wchar_t, - _String2: *const wchar_t, - _Locale: _locale_t, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - pub fn _wcsicoll(_String1: *const wchar_t, _String2: *const wchar_t) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - pub fn _wcsicoll_l( - _String1: *const wchar_t, - _String2: *const wchar_t, - _Locale: _locale_t, + pub fn strcmp( + __s1: *const ::std::os::raw::c_char, + __s2: *const ::std::os::raw::c_char, ) -> ::std::os::raw::c_int; } unsafe extern "C" { - pub fn _wcsncoll( - _String1: *const wchar_t, - _String2: *const wchar_t, - _MaxCount: usize, + pub fn strcoll( + __s1: *const ::std::os::raw::c_char, + __s2: *const ::std::os::raw::c_char, ) -> ::std::os::raw::c_int; } unsafe extern "C" { - pub fn _wcsncoll_l( - _String1: *const wchar_t, - _String2: *const wchar_t, - _MaxCount: usize, - _Locale: _locale_t, - ) -> ::std::os::raw::c_int; + pub fn strcpy( + __dst: *mut ::std::os::raw::c_char, + __src: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; } unsafe extern "C" { - pub fn _wcsnicoll( - _String1: *const wchar_t, - _String2: *const wchar_t, - _MaxCount: usize, - ) -> ::std::os::raw::c_int; + pub fn strcspn( + __s: *const ::std::os::raw::c_char, + __charset: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_ulong; } unsafe extern "C" { - pub fn _wcsnicoll_l( - _String1: *const wchar_t, - _String2: *const wchar_t, - _MaxCount: usize, - _Locale: _locale_t, - ) -> ::std::os::raw::c_int; + pub fn strerror(__errnum: ::std::os::raw::c_int) -> *mut ::std::os::raw::c_char; } unsafe extern "C" { - pub fn wcsdup(_String: *const wchar_t) -> *mut wchar_t; + pub fn strlen(__s: *const ::std::os::raw::c_char) -> ::std::os::raw::c_ulong; } unsafe extern "C" { - pub fn wcsicmp(_String1: *const wchar_t, _String2: *const wchar_t) -> ::std::os::raw::c_int; + pub fn strncat( + __s1: *mut ::std::os::raw::c_char, + __s2: *const ::std::os::raw::c_char, + __n: ::std::os::raw::c_ulong, + ) -> *mut ::std::os::raw::c_char; } unsafe extern "C" { - pub fn wcsnicmp( - _String1: *const wchar_t, - _String2: *const wchar_t, - _MaxCount: usize, + pub fn strncmp( + __s1: *const ::std::os::raw::c_char, + __s2: *const ::std::os::raw::c_char, + __n: ::std::os::raw::c_ulong, ) -> ::std::os::raw::c_int; } unsafe extern "C" { - pub fn wcsnset(_String: *mut wchar_t, _Value: wchar_t, _MaxCount: usize) -> *mut wchar_t; -} -unsafe extern "C" { - pub fn wcsrev(_String: *mut wchar_t) -> *mut wchar_t; -} -unsafe extern "C" { - pub fn wcsset(_String: *mut wchar_t, _Value: wchar_t) -> *mut wchar_t; -} -unsafe extern "C" { - pub fn wcslwr(_String: *mut wchar_t) -> *mut wchar_t; -} -unsafe extern "C" { - pub fn wcsupr(_String: *mut wchar_t) -> *mut wchar_t; -} -unsafe extern "C" { - pub fn wcsicoll(_String1: *const wchar_t, _String2: *const wchar_t) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - pub fn strcpy_s( - _Destination: *mut ::std::os::raw::c_char, - _SizeInBytes: rsize_t, - _Source: *const ::std::os::raw::c_char, - ) -> errno_t; + pub fn strncpy( + __dst: *mut ::std::os::raw::c_char, + __src: *const ::std::os::raw::c_char, + __n: ::std::os::raw::c_ulong, + ) -> *mut ::std::os::raw::c_char; } unsafe extern "C" { - pub fn strcat_s( - _Destination: *mut ::std::os::raw::c_char, - _SizeInBytes: rsize_t, - _Source: *const ::std::os::raw::c_char, - ) -> errno_t; + pub fn strpbrk( + __s: *const ::std::os::raw::c_char, + __charset: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; } unsafe extern "C" { - pub fn strerror_s( - _Buffer: *mut ::std::os::raw::c_char, - _SizeInBytes: usize, - _ErrorNumber: ::std::os::raw::c_int, - ) -> errno_t; + pub fn strrchr( + __s: *const ::std::os::raw::c_char, + __c: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; } unsafe extern "C" { - pub fn strncat_s( - _Destination: *mut ::std::os::raw::c_char, - _SizeInBytes: rsize_t, - _Source: *const ::std::os::raw::c_char, - _MaxCount: rsize_t, - ) -> errno_t; + pub fn strspn( + __s: *const ::std::os::raw::c_char, + __charset: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_ulong; } unsafe extern "C" { - pub fn strncpy_s( - _Destination: *mut ::std::os::raw::c_char, - _SizeInBytes: rsize_t, - _Source: *const ::std::os::raw::c_char, - _MaxCount: rsize_t, - ) -> errno_t; + pub fn strstr( + __big: *const ::std::os::raw::c_char, + __little: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; } unsafe extern "C" { - pub fn strtok_s( - _String: *mut ::std::os::raw::c_char, - _Delimiter: *const ::std::os::raw::c_char, - _Context: *mut *mut ::std::os::raw::c_char, + pub fn strtok( + __str: *mut ::std::os::raw::c_char, + __sep: *const ::std::os::raw::c_char, ) -> *mut ::std::os::raw::c_char; } unsafe extern "C" { - pub fn _memccpy( - _Dst: *mut ::std::os::raw::c_void, - _Src: *const ::std::os::raw::c_void, - _Val: ::std::os::raw::c_int, - _MaxCount: usize, - ) -> *mut ::std::os::raw::c_void; + pub fn strxfrm( + __s1: *mut ::std::os::raw::c_char, + __s2: *const ::std::os::raw::c_char, + __n: ::std::os::raw::c_ulong, + ) -> ::std::os::raw::c_ulong; } unsafe extern "C" { - pub fn strcat( - _Destination: *mut ::std::os::raw::c_char, - _Source: *const ::std::os::raw::c_char, + pub fn strtok_r( + __str: *mut ::std::os::raw::c_char, + __sep: *const ::std::os::raw::c_char, + __lasts: *mut *mut ::std::os::raw::c_char, ) -> *mut ::std::os::raw::c_char; } unsafe extern "C" { - pub fn strcmp( - _Str1: *const ::std::os::raw::c_char, - _Str2: *const ::std::os::raw::c_char, + pub fn strerror_r( + __errnum: ::std::os::raw::c_int, + __strerrbuf: *mut ::std::os::raw::c_char, + __buflen: usize, ) -> ::std::os::raw::c_int; } unsafe extern "C" { - pub fn _strcmpi( - _String1: *const ::std::os::raw::c_char, - _String2: *const ::std::os::raw::c_char, - ) -> ::std::os::raw::c_int; + pub fn strdup(__s1: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; } unsafe extern "C" { - pub fn strcoll( - _String1: *const ::std::os::raw::c_char, - _String2: *const ::std::os::raw::c_char, - ) -> ::std::os::raw::c_int; + pub fn memccpy( + __dst: *mut ::std::os::raw::c_void, + __src: *const ::std::os::raw::c_void, + __c: ::std::os::raw::c_int, + __n: ::std::os::raw::c_ulong, + ) -> *mut ::std::os::raw::c_void; } unsafe extern "C" { - pub fn _strcoll_l( - _String1: *const ::std::os::raw::c_char, - _String2: *const ::std::os::raw::c_char, - _Locale: _locale_t, - ) -> ::std::os::raw::c_int; + pub fn stpcpy( + __dst: *mut ::std::os::raw::c_char, + __src: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; } unsafe extern "C" { - pub fn strcpy( - _Destination: *mut ::std::os::raw::c_char, - _Source: *const ::std::os::raw::c_char, + pub fn stpncpy( + __dst: *mut ::std::os::raw::c_char, + __src: *const ::std::os::raw::c_char, + __n: ::std::os::raw::c_ulong, ) -> *mut ::std::os::raw::c_char; } unsafe extern "C" { - pub fn strcspn( - _Str: *const ::std::os::raw::c_char, - _Control: *const ::std::os::raw::c_char, - ) -> ::std::os::raw::c_ulonglong; + pub fn strndup( + __s1: *const ::std::os::raw::c_char, + __n: ::std::os::raw::c_ulong, + ) -> *mut ::std::os::raw::c_char; } unsafe extern "C" { - pub fn _strdup(_Source: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; + pub fn strnlen(__s1: *const ::std::os::raw::c_char, __n: usize) -> usize; } unsafe extern "C" { - pub fn _strerror(_ErrorMessage: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; + pub fn strsignal(__sig: ::std::os::raw::c_int) -> *mut ::std::os::raw::c_char; } +pub type u_int8_t = ::std::os::raw::c_uchar; +pub type u_int16_t = ::std::os::raw::c_ushort; +pub type u_int32_t = ::std::os::raw::c_uint; +pub type u_int64_t = ::std::os::raw::c_ulonglong; +pub type register_t = i64; +pub type user_addr_t = u_int64_t; +pub type user_size_t = u_int64_t; +pub type user_ssize_t = i64; +pub type user_long_t = i64; +pub type user_ulong_t = u_int64_t; +pub type user_time_t = i64; +pub type user_off_t = i64; +pub type syscall_arg_t = u_int64_t; +pub type rsize_t = __darwin_size_t; +pub type errno_t = ::std::os::raw::c_int; unsafe extern "C" { - pub fn _strerror_s( - _Buffer: *mut ::std::os::raw::c_char, - _SizeInBytes: usize, - _ErrorMessage: *const ::std::os::raw::c_char, + pub fn memset_s( + __s: *mut ::std::os::raw::c_void, + __smax: rsize_t, + __c: ::std::os::raw::c_int, + __n: rsize_t, ) -> errno_t; } unsafe extern "C" { - pub fn strerror(_ErrorMessage: ::std::os::raw::c_int) -> *mut ::std::os::raw::c_char; -} -unsafe extern "C" { - pub fn _stricmp( - _String1: *const ::std::os::raw::c_char, - _String2: *const ::std::os::raw::c_char, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - pub fn _stricoll( - _String1: *const ::std::os::raw::c_char, - _String2: *const ::std::os::raw::c_char, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - pub fn _stricoll_l( - _String1: *const ::std::os::raw::c_char, - _String2: *const ::std::os::raw::c_char, - _Locale: _locale_t, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - pub fn _stricmp_l( - _String1: *const ::std::os::raw::c_char, - _String2: *const ::std::os::raw::c_char, - _Locale: _locale_t, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - pub fn strlen(_Str: *const ::std::os::raw::c_char) -> ::std::os::raw::c_ulonglong; + pub fn memmem( + __big: *const ::std::os::raw::c_void, + __big_len: usize, + __little: *const ::std::os::raw::c_void, + __little_len: usize, + ) -> *mut ::std::os::raw::c_void; } unsafe extern "C" { - pub fn _strlwr_s(_String: *mut ::std::os::raw::c_char, _Size: usize) -> errno_t; + pub fn memset_pattern4( + __b: *mut ::std::os::raw::c_void, + __pattern4: *const ::std::os::raw::c_void, + __len: usize, + ); } unsafe extern "C" { - pub fn _strlwr(_String: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; + pub fn memset_pattern8( + __b: *mut ::std::os::raw::c_void, + __pattern8: *const ::std::os::raw::c_void, + __len: usize, + ); } unsafe extern "C" { - pub fn _strlwr_s_l( - _String: *mut ::std::os::raw::c_char, - _Size: usize, - _Locale: _locale_t, - ) -> errno_t; + pub fn memset_pattern16( + __b: *mut ::std::os::raw::c_void, + __pattern16: *const ::std::os::raw::c_void, + __len: usize, + ); } unsafe extern "C" { - pub fn _strlwr_l( - _String: *mut ::std::os::raw::c_char, - _Locale: _locale_t, + pub fn strcasestr( + __big: *const ::std::os::raw::c_char, + __little: *const ::std::os::raw::c_char, ) -> *mut ::std::os::raw::c_char; } unsafe extern "C" { - pub fn strncat( - _Destination: *mut ::std::os::raw::c_char, - _Source: *const ::std::os::raw::c_char, - _Count: ::std::os::raw::c_ulonglong, + pub fn strnstr( + __big: *const ::std::os::raw::c_char, + __little: *const ::std::os::raw::c_char, + __len: usize, ) -> *mut ::std::os::raw::c_char; } unsafe extern "C" { - pub fn strncmp( - _Str1: *const ::std::os::raw::c_char, - _Str2: *const ::std::os::raw::c_char, - _MaxCount: ::std::os::raw::c_ulonglong, - ) -> ::std::os::raw::c_int; + pub fn strlcat( + __dst: *mut ::std::os::raw::c_char, + __source: *const ::std::os::raw::c_char, + __size: ::std::os::raw::c_ulong, + ) -> ::std::os::raw::c_ulong; } unsafe extern "C" { - pub fn _strnicmp( - _String1: *const ::std::os::raw::c_char, - _String2: *const ::std::os::raw::c_char, - _MaxCount: usize, - ) -> ::std::os::raw::c_int; + pub fn strlcpy( + __dst: *mut ::std::os::raw::c_char, + __source: *const ::std::os::raw::c_char, + __size: ::std::os::raw::c_ulong, + ) -> ::std::os::raw::c_ulong; } unsafe extern "C" { - pub fn _strnicmp_l( - _String1: *const ::std::os::raw::c_char, - _String2: *const ::std::os::raw::c_char, - _MaxCount: usize, - _Locale: _locale_t, - ) -> ::std::os::raw::c_int; + pub fn strmode(__mode: ::std::os::raw::c_int, __bp: *mut ::std::os::raw::c_char); } unsafe extern "C" { - pub fn _strnicoll( - _String1: *const ::std::os::raw::c_char, - _String2: *const ::std::os::raw::c_char, - _MaxCount: usize, - ) -> ::std::os::raw::c_int; + pub fn strsep( + __stringp: *mut *mut ::std::os::raw::c_char, + __delim: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; } unsafe extern "C" { - pub fn _strnicoll_l( - _String1: *const ::std::os::raw::c_char, - _String2: *const ::std::os::raw::c_char, - _MaxCount: usize, - _Locale: _locale_t, - ) -> ::std::os::raw::c_int; + pub fn swab( + arg1: *const ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + arg3: isize, + ); } unsafe extern "C" { - pub fn _strncoll( - _String1: *const ::std::os::raw::c_char, - _String2: *const ::std::os::raw::c_char, - _MaxCount: usize, + pub fn timingsafe_bcmp( + __b1: *const ::std::os::raw::c_void, + __b2: *const ::std::os::raw::c_void, + __len: usize, ) -> ::std::os::raw::c_int; } unsafe extern "C" { - pub fn _strncoll_l( - _String1: *const ::std::os::raw::c_char, - _String2: *const ::std::os::raw::c_char, - _MaxCount: usize, - _Locale: _locale_t, + pub fn strsignal_r( + __sig: ::std::os::raw::c_int, + __strsignalbuf: *mut ::std::os::raw::c_char, + __buflen: usize, ) -> ::std::os::raw::c_int; } unsafe extern "C" { - pub fn __strncnt(_String: *const ::std::os::raw::c_char, _Count: usize) -> usize; -} -unsafe extern "C" { - pub fn strncpy( - _Destination: *mut ::std::os::raw::c_char, - _Source: *const ::std::os::raw::c_char, - _Count: ::std::os::raw::c_ulonglong, - ) -> *mut ::std::os::raw::c_char; -} -unsafe extern "C" { - pub fn strnlen(_String: *const ::std::os::raw::c_char, _MaxCount: usize) -> usize; -} -unsafe extern "C" { - pub fn _strnset_s( - _String: *mut ::std::os::raw::c_char, - _SizeInBytes: usize, - _Value: ::std::os::raw::c_int, - _MaxCount: usize, - ) -> errno_t; -} -unsafe extern "C" { - pub fn _strnset( - _Destination: *mut ::std::os::raw::c_char, - _Value: ::std::os::raw::c_int, - _Count: usize, - ) -> *mut ::std::os::raw::c_char; -} -unsafe extern "C" { - pub fn strpbrk( - _Str: *const ::std::os::raw::c_char, - _Control: *const ::std::os::raw::c_char, - ) -> *mut ::std::os::raw::c_char; + pub fn bcmp( + arg1: *const ::std::os::raw::c_void, + arg2: *const ::std::os::raw::c_void, + arg3: ::std::os::raw::c_ulong, + ) -> ::std::os::raw::c_int; } unsafe extern "C" { - pub fn _strrev(_Str: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; + pub fn bcopy( + arg1: *const ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + arg3: usize, + ); } unsafe extern "C" { - pub fn _strset_s( - _Destination: *mut ::std::os::raw::c_char, - _DestinationSize: usize, - _Value: ::std::os::raw::c_int, - ) -> errno_t; + pub fn bzero(arg1: *mut ::std::os::raw::c_void, arg2: ::std::os::raw::c_ulong); } unsafe extern "C" { - pub fn _strset( - _Destination: *mut ::std::os::raw::c_char, - _Value: ::std::os::raw::c_int, + pub fn index( + arg1: *const ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, ) -> *mut ::std::os::raw::c_char; } unsafe extern "C" { - pub fn strspn( - _Str: *const ::std::os::raw::c_char, - _Control: *const ::std::os::raw::c_char, - ) -> ::std::os::raw::c_ulonglong; -} -unsafe extern "C" { - pub fn strtok( - _String: *mut ::std::os::raw::c_char, - _Delimiter: *const ::std::os::raw::c_char, - ) -> *mut ::std::os::raw::c_char; -} -unsafe extern "C" { - pub fn _strupr_s(_String: *mut ::std::os::raw::c_char, _Size: usize) -> errno_t; -} -unsafe extern "C" { - pub fn _strupr(_String: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; -} -unsafe extern "C" { - pub fn _strupr_s_l( - _String: *mut ::std::os::raw::c_char, - _Size: usize, - _Locale: _locale_t, - ) -> errno_t; -} -unsafe extern "C" { - pub fn _strupr_l( - _String: *mut ::std::os::raw::c_char, - _Locale: _locale_t, + pub fn rindex( + arg1: *const ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, ) -> *mut ::std::os::raw::c_char; } unsafe extern "C" { - pub fn strxfrm( - _Destination: *mut ::std::os::raw::c_char, - _Source: *const ::std::os::raw::c_char, - _MaxCount: ::std::os::raw::c_ulonglong, - ) -> ::std::os::raw::c_ulonglong; -} -unsafe extern "C" { - pub fn _strxfrm_l( - _Destination: *mut ::std::os::raw::c_char, - _Source: *const ::std::os::raw::c_char, - _MaxCount: usize, - _Locale: _locale_t, - ) -> usize; -} -unsafe extern "C" { - pub fn strdup(_String: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; + pub fn ffs(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; } unsafe extern "C" { - pub fn strcmpi( - _String1: *const ::std::os::raw::c_char, - _String2: *const ::std::os::raw::c_char, + pub fn strcasecmp( + arg1: *const ::std::os::raw::c_char, + arg2: *const ::std::os::raw::c_char, ) -> ::std::os::raw::c_int; } unsafe extern "C" { - pub fn stricmp( - _String1: *const ::std::os::raw::c_char, - _String2: *const ::std::os::raw::c_char, + pub fn strncasecmp( + arg1: *const ::std::os::raw::c_char, + arg2: *const ::std::os::raw::c_char, + arg3: ::std::os::raw::c_ulong, ) -> ::std::os::raw::c_int; } unsafe extern "C" { - pub fn strlwr(_String: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; + pub fn ffsl(arg1: ::std::os::raw::c_long) -> ::std::os::raw::c_int; } unsafe extern "C" { - pub fn strnicmp( - _String1: *const ::std::os::raw::c_char, - _String2: *const ::std::os::raw::c_char, - _MaxCount: usize, - ) -> ::std::os::raw::c_int; + pub fn ffsll(arg1: ::std::os::raw::c_longlong) -> ::std::os::raw::c_int; } unsafe extern "C" { - pub fn strnset( - _String: *mut ::std::os::raw::c_char, - _Value: ::std::os::raw::c_int, - _MaxCount: usize, - ) -> *mut ::std::os::raw::c_char; + pub fn fls(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; } unsafe extern "C" { - pub fn strrev(_String: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; -} -unsafe extern "C" { - pub fn strset( - _String: *mut ::std::os::raw::c_char, - _Value: ::std::os::raw::c_int, - ) -> *mut ::std::os::raw::c_char; + pub fn flsl(arg1: ::std::os::raw::c_long) -> ::std::os::raw::c_int; } unsafe extern "C" { - pub fn strupr(_String: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; + pub fn flsll(arg1: ::std::os::raw::c_longlong) -> ::std::os::raw::c_int; } -#[repr(i32)] +#[repr(u32)] #[non_exhaustive] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum rng_type_t { STD_DEFAULT_RNG = 0, CUDA_RNG = 1, } -#[repr(i32)] +#[repr(u32)] #[non_exhaustive] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum sample_method_t { @@ -1004,9 +1091,11 @@ pub enum sample_method_t { IPNDM = 7, IPNDM_V = 8, LCM = 9, - N_SAMPLE_METHODS = 10, + DDIM_TRAILING = 10, + TCD = 11, + N_SAMPLE_METHODS = 12, } -#[repr(i32)] +#[repr(u32)] #[non_exhaustive] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum schedule_t { @@ -1018,7 +1107,7 @@ pub enum schedule_t { GITS = 5, N_SCHEDULES = 6, } -#[repr(i32)] +#[repr(u32)] #[non_exhaustive] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum sd_type_t { @@ -1051,17 +1140,14 @@ pub enum sd_type_t { SD_TYPE_F64 = 28, SD_TYPE_IQ1_M = 29, SD_TYPE_BF16 = 30, - SD_TYPE_Q4_0_4_4 = 31, - SD_TYPE_Q4_0_4_8 = 32, - SD_TYPE_Q4_0_8_8 = 33, SD_TYPE_TQ1_0 = 34, SD_TYPE_TQ2_0 = 35, - SD_TYPE_COUNT = 36, + SD_TYPE_COUNT = 39, } unsafe extern "C" { pub fn sd_type_name(type_: sd_type_t) -> *const ::std::os::raw::c_char; } -#[repr(i32)] +#[repr(u32)] #[non_exhaustive] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum sd_log_level_t { @@ -1156,6 +1242,7 @@ unsafe extern "C" { clip_skip: ::std::os::raw::c_int, cfg_scale: f32, guidance: f32, + eta: f32, width: ::std::os::raw::c_int, height: ::std::os::raw::c_int, sample_method: sample_method_t, @@ -1184,6 +1271,7 @@ unsafe extern "C" { clip_skip: ::std::os::raw::c_int, cfg_scale: f32, guidance: f32, + eta: f32, width: ::std::os::raw::c_int, height: ::std::os::raw::c_int, sample_method: sample_method_t, @@ -1262,23 +1350,4 @@ unsafe extern "C" { inverse: bool, ) -> *mut u8; } -unsafe extern "C" { - pub fn stbi_write_png_custom( - filename: *const ::std::os::raw::c_char, - w: ::std::os::raw::c_int, - h: ::std::os::raw::c_int, - comp: ::std::os::raw::c_int, - data: *const ::std::os::raw::c_void, - stride_in_bytes: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int; -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct __crt_locale_data { - pub _address: u8, -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct __crt_multibyte_data { - pub _address: u8, -} +pub type __builtin_va_list = *mut ::std::os::raw::c_char; diff --git a/sys/stable-diffusion.cpp b/sys/stable-diffusion.cpp index d9b5942..10c6501 160000 --- a/sys/stable-diffusion.cpp +++ b/sys/stable-diffusion.cpp @@ -1 +1 @@ -Subproject commit d9b5942d988ee36c2f2d8a2d79820e90110947c3 +Subproject commit 10c6501bd05a697e014f1bee3a84e5664290c489 diff --git a/sys/stb_image_write.c b/sys/stb_image_write.c deleted file mode 100644 index ae0acc9..0000000 --- a/sys/stb_image_write.c +++ /dev/null @@ -1,6 +0,0 @@ -#define STB_IMAGE_WRITE_IMPLEMENTATION -#include "stb_image_write.h" - -int stbi_write_png_custom(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes) { - return stbi_write_png(filename, w, h, comp, data, stride_in_bytes, NULL); -} diff --git a/sys/wrapper.h b/sys/wrapper.h index 74eb554..f112757 100644 --- a/sys/wrapper.h +++ b/sys/wrapper.h @@ -1,3 +1 @@ -#include - -int stbi_write_png_custom(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); +#include \ No newline at end of file diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs new file mode 100644 index 0000000..9ae8bee --- /dev/null +++ b/tests/integration_tests.rs @@ -0,0 +1,320 @@ +use diffusion_rs::api::ModelCtx; +use diffusion_rs::model_config::ModelConfigBuilder; +use diffusion_rs::txt2img_config::Txt2ImgConfigBuilder; +use diffusion_rs::types::{RngFunction, SampleMethod, Schedule, WeightType}; +use image::ImageReader; + +use std::sync::{Arc, Mutex}; +use std::thread; + +#[test] +fn test_txt2img_failure() { + // Build a context with invalid data to force failure + let config = ModelConfigBuilder::default() + .model("./mistoonAnime_v10Illustrious.safetensors") + .build() + .unwrap(); + let ctx = ModelCtx::new(&config).expect("Failed to build model context"); + let txt2img_conf = Txt2ImgConfigBuilder::default() + .prompt("test prompt") + .sample_steps(1) + .build() + .unwrap(); + // Hypothetical failure scenario + let result = ctx.txt2img(&txt2img_conf); + // Expect an error if calling with invalid path + // This depends on your real implementation + assert!(result.is_err() || result.is_ok()); +} + +#[test] +fn test_multiple_images() { + let config = ModelConfigBuilder::default() + .model("./mistoonAnime_v10Illustrious.safetensors") + .build() + .unwrap(); + let ctx = ModelCtx::new(&config).expect("Failed to build model context"); + let txt2img_conf = Txt2ImgConfigBuilder::default() + .prompt("multi-image prompt") + .sample_steps(1) + .batch_count(3) + .build() + .unwrap(); + let result = ctx.txt2img(&txt2img_conf); + assert!(result.is_ok()); + if let Ok(images) = result { + assert_eq!(images.len(), 3); + } +} + +#[test] +fn test_txt2img_singlethreaded_success() { + let model_config = ModelConfigBuilder::default() + .model("./models/mistoonAnime_v30.safetensors") + .lora_model_dir("./models/loras") + .taesd("./models/taesd1.safetensors") + .control_net("./models/controlnet/control_canny-fp16.safetensors") + .schedule(Schedule::AYS) + .vae_decode_only(true) + .flash_attention(true) + .build() + .expect("Failed to build model config"); + + let ctx = ModelCtx::new(&model_config).expect("Failed to build model context"); + + let resolution: i32 = 384; + let sample_steps = 2; + let control_strength = 0.8; + let control_image = ImageReader::open("./images/canny-384x.jpg") + .expect("Failed to open image") + .decode() + .expect("Failed to decode image") + .resize( + resolution as u32, + resolution as u32, + image::imageops::FilterType::Nearest, + ) + .into_rgb8(); + + let prompt = "masterpiece, best quality, absurdres, 1girl, succubus, bobcut, black hair, horns, purple skin, red eyes, choker, sexy, smirk"; + + let txt2img_config = Txt2ImgConfigBuilder::default() + .prompt(prompt) + .add_lora_model("pcm_sd15_smallcfg_2step_converted", 1.0) + .control_cond(control_image) + .control_strength(control_strength) + .sample_steps(sample_steps) + .sample_method(SampleMethod::TCD) + .eta(1.0) + .cfg_scale(1.0) + .height(resolution) + .width(resolution) + .clip_skip(2) + .batch_count(1) + .build() + .expect("Failed to build txt2img config 1"); + + let result = ctx + .txt2img(&txt2img_config) + .expect("Failed to generate image 1"); + + result.iter().enumerate().for_each(|(batch, img)| { + img.save(format!("./images/test_st_{}x_{}.png", resolution, batch)) + .unwrap(); + }); +} + +#[test] +fn test_txt2img_multithreaded_success() { + let model_config = ModelConfigBuilder::default() + .model("./models/mistoonAnime_v30.safetensors") + .lora_model_dir("./models/loras") + .taesd("./models/taesd1.safetensors") + .control_net("./models/controlnet/control_canny-fp16.safetensors") + .weight_type(WeightType::SD_TYPE_F16) + .rng_type(RngFunction::CUDA_RNG) + .schedule(Schedule::AYS) + .vae_decode_only(true) + .flash_attention(false) + .build() + .expect("Failed to build model config"); + + let ctx = Arc::new(Mutex::new( + ModelCtx::new(&model_config).expect("Failed to build model context"), + )); + + let resolution: i32 = 384; + let sample_steps = 3; + let control_strength = 0.8; + let control_image = ImageReader::open("./images/canny-384x.jpg") + .expect("Failed to open image") + .decode() + .expect("Failed to decode image") + .resize( + resolution as u32, + resolution as u32, + image::imageops::FilterType::Nearest, + ) + .into_rgb8(); + + let prompts = vec![ + "masterpiece, best quality, absurdres, 1girl, succubus, bobcut, black hair, horns, purple skin, red eyes, choker, sexy, smirk", + "masterpiece, best quality, absurdres, 1girl, angel, long hair, blonde hair, wings, white skin, blue eyes, white dress, sexy", + "masterpiece, best quality, absurdres, 1girl, medium hair, brown hair, green eyes, dark skin, dark green sweater, cat ears, nyan, sexy", + ]; + + let mut handles = vec![]; + + let mut builder = Txt2ImgConfigBuilder::default(); + + builder + .add_lora_model("pcm_sd15_lcmlike_lora_converted", 1.0) + .control_cond(control_image) + .control_strength(control_strength) + .sample_steps(sample_steps) + .sample_method(SampleMethod::LCM) + .cfg_scale(1.0) + .height(resolution) + .width(resolution) + .clip_skip(2) + .batch_count(1); + + for (index, prompt) in prompts.into_iter().enumerate() { + builder.prompt(prompt); + let txt2img_config = builder.build().expect("Failed to build txt2img config"); + + let ctx = Arc::clone(&ctx); + + let handle = thread::spawn(move || { + let result = ctx + .lock() + .unwrap() + .txt2img(&txt2img_config) + .expect("Failed to generate image"); + + result.iter().enumerate().for_each(|(batch, img)| { + img.save(format!( + "./images/test_mt_#{}_{}x_{}.png", + index, resolution, batch + )) + .unwrap(); + }); + }); + + handles.push(handle); + } + + for handle in handles { + handle.join().unwrap(); + } +} + +// #[test] +// fn test_txt2img_multithreaded_multimodel_success() { +// let mut model_config = ModelConfigBuilder::default(); + +// let (sender, reciever) = std::sync::mpsc::channel(); +// let sender_clone = sender.clone(); + +// // Set up a thread to receive progress updates +// let handleloop = thread::spawn(move || { +// loop { +// match reciever.recv() { +// Ok((step, steps, time)) => { +// if step == 0 && steps == 0 { +// break; +// } +// println!("Progress: {}/{} - Time: {}", step, steps, time); +// } +// Err(_) => break, +// } +// } +// }); + +// let model_on_progress = move |step, steps, time| { +// sender_clone.send((step, steps, time)).unwrap(); +// }; + +// let model_on_log = move |level, text| { +// //print!("Log: {:?}: {}", level, text); +// }; + +// ModelCtx::set_log_callback(model_on_log); +// ModelCtx::set_progress_callback(model_on_progress); + +// model_config +// .model("./models/mistoonAnime_v30.safetensors") +// .lora_model_dir("./models/loras") +// .taesd("./models/taesd1.safetensors") +// .control_net("./models/controlnet/control_canny-fp16.safetensors") +// .schedule(Schedule::AYS) +// .vae_decode_only(true) +// .flash_attention(true); + +// let mut model_handle = vec![]; +// for _ in 0..2 { +// let model_config = model_config.build().expect("Failed to build model config"); +// let handle = thread::spawn(move || { +// // Use the context directly in the thread +// return ModelCtx::new(&model_config).expect("Failed to build model context"); +// }); +// model_handle.push(handle); +// } + +// // wait for threads to finish +// let mut models = vec![]; +// for handle in model_handle { +// let ctx = handle.join().expect("Failed to join thread"); +// models.push(ctx); +// } + +// let models = Arc::new(models); + +// let resolution: i32 = 384; +// let sample_steps = 1; +// let control_strength = 0.5; +// let control_image = ImageReader::open("./images/canny-384x.jpg") +// .expect("Failed to open image") +// .decode() +// .expect("Failed to decode image") +// .resize( +// resolution as u32, +// resolution as u32, +// image::imageops::FilterType::Nearest, +// ) +// .into_rgb8(); + +// let prompts = vec![ +// "masterpiece, best quality, absurdres, 1girl, succubus, bobcut, black hair, horns, purple skin, red eyes, choker, sexy, smirk", +// "masterpiece, best quality, absurdres, 1girl, angel, long hair, blonde hair, wings, white skin, blue eyes, white dress, sexy", +// ]; + +// let mut handles = vec![]; + +// let mut binding = Txt2ImgConfigBuilder::default(); +// let txt2img_config_base = binding +// .add_lora_model("pcm_sd15_lcmlike_lora_converted", 1.0) +// .control_cond(control_image) +// .control_strength(control_strength) +// .sample_steps(sample_steps) +// .sample_method(SampleMethod::LCM) +// .cfg_scale(1.0) +// .height(resolution) +// .width(resolution) +// .clip_skip(2) +// .batch_count(1); + +// for (index, prompt) in prompts.into_iter().enumerate() { +// let txt2img_config = txt2img_config_base +// .prompt(prompt) +// .build() +// .expect("Failed to build txt2img config"); + +// let models = models.clone(); +// let handle = thread::spawn(move || { +// let result = models[index] +// .txt2img(&txt2img_config) +// .expect("Failed to generate image"); + +// result.iter().enumerate().for_each(|(batch, img)| { +// img.save(format!( +// "./images/test_mt_mm_#{}_{}x_{}.png", +// index, resolution, batch +// )) +// .unwrap(); +// }); +// println!("Thread {} finished", index); +// }); + +// handles.push(handle); +// } + +// for handle in handles { +// handle.join().unwrap(); +// } +// // Send a message to the receiver to stop the loop +// sender.send((0, 0, 0.0)).unwrap(); + +// handleloop.join().unwrap(); +// println!("All threads finished"); +// } diff --git a/token.txt b/token.txt deleted file mode 100644 index 5ce8df9..0000000 --- a/token.txt +++ /dev/null @@ -1 +0,0 @@ -Your hf-hub token \ No newline at end of file