From d23c6185b08daedc4d4b768eb0ca7c2a7c81af6e Mon Sep 17 00:00:00 2001 From: Michiel Date: Wed, 18 Dec 2024 20:48:02 +0100 Subject: [PATCH] New 6.1.3 using QOI C library (#131) * Improve formatting * Remove old 6.1.3 * Add new 6.1.3 using QOI C library * Fix TODO left in text * Add unit test to compare C library and image crate --- .vscode/settings.json | 2 +- book/src/foreign-function-interface.md | 356 ++---- .../3-qoi-bindgen/Cargo.lock | 1009 +++++++++++++++++ .../3-qoi-bindgen/Cargo.toml | 8 + .../3-qoi-bindgen/image.qoi | Bin 0 -> 237804 bytes .../3-qoi-bindgen/qoi.c | 2 + .../3-qoi-bindgen/qoi.h | 649 +++++++++++ .../3-qoi-bindgen/src/main.rs | 11 + .../3-tweetnacl-bindgen/Cargo.lock | 7 - .../3-tweetnacl-bindgen/Cargo.toml | 8 - .../3-tweetnacl-bindgen/src/lib.rs | 1 - .../3-tweetnacl-bindgen/src/main.rs | 3 - .../3-tweetnacl-bindgen/tweetnacl.c | 784 ------------- .../3-tweetnacl-bindgen/tweetnacl.h | 272 ----- 14 files changed, 1803 insertions(+), 1309 deletions(-) create mode 100644 exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-qoi-bindgen/Cargo.lock create mode 100644 exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-qoi-bindgen/Cargo.toml create mode 100644 exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-qoi-bindgen/image.qoi create mode 100644 exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-qoi-bindgen/qoi.c create mode 100644 exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-qoi-bindgen/qoi.h create mode 100644 exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-qoi-bindgen/src/main.rs delete mode 100644 exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/Cargo.lock delete mode 100644 exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/Cargo.toml delete mode 100644 exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/src/lib.rs delete mode 100644 exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/src/main.rs delete mode 100644 exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/tweetnacl.c delete mode 100644 exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/tweetnacl.h diff --git a/.vscode/settings.json b/.vscode/settings.json index aee1699..c06767c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -25,7 +25,7 @@ "exercises/4-multitasking/3-asynchronous-multitasking/2-async-chat/Cargo.toml", "exercises/6-rust-for-systems-programming/1-foreign-function-interface/1-crc-in-c/Cargo.toml", "exercises/6-rust-for-systems-programming/1-foreign-function-interface/2-crc-in-rust/Cargo.toml", - "exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/Cargo.toml", + "exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-qoi-bindgen/Cargo.toml", "exercises/7-rust-for-data-science/1-rust-from-python/1-hello-world/Cargo.toml", "exercises/7-rust-for-data-science/1-rust-from-python/2-strompy/Cargo.toml", "exercises/8-embedded/1-embedded-ecosystem/1-lsm303agr-id/Cargo.toml", diff --git a/book/src/foreign-function-interface.md b/book/src/foreign-function-interface.md index fb6e988..150431b 100644 --- a/book/src/foreign-function-interface.md +++ b/book/src/foreign-function-interface.md @@ -4,14 +4,15 @@ ## Exercise 6.1.1: CRC in C -Use a CRC checksum function written in C in a Rust program +In this exercise, we will call a CRC checksum function written in C from a Rust program. -## prerequisites +### Instructions -- A C compiler +Prerequisites: +- A C compiler -## Steps +Steps: 1. Add the `cc` build dependency, by adding to `Cargo.toml` the lines: ```toml @@ -51,15 +52,18 @@ Use a CRC checksum function written in C in a Rust program } ``` In the above example, the correct output is `0x9ae0daaf` + ## Exercise 6.1.2: CRC in Rust -Use a CRC checksum function written in Rust in a C program +Now, let's do it the other way around: we can use a CRC checksum function written in Rust in a C program. + +### Instructions -## Requirements +Prerequisites: - A C compiler -## Steps +Steps: 1. Change Cargo.toml to @@ -142,36 +146,30 @@ Use a CRC checksum function written in Rust in a C program Hash: -1386739207 ``` -## Exercise 6.1.3: TweetNaCl Bindgen +## Exercise 6.1.3: QOI Bindgen +In this exercise, we will use `cargo bindgen` to generate the FFI bindings for a C library. Bindgen will look at a C header file, and generate Rust functions, types and constants based on the C definitions. -Use `cargo bindgen` to generate the FFI bindings. Bindgen will look at a C header file, and generate rust functions, types and constants based on the C definitions. +However, the generated code will likely be ugly and non-idiomatic. To wrap a C library properly, good API design and documentation is needed. -But the generated code is ugly and non-idiomatic. To wrap a C library properly, good API design and documentation is needed. +### Background +The [image crate](https://crates.io/crates/image) provides functionality for encoding, decoding and editing images in Rust. It supports many image formats, like JPEG, PNG and GIF, but also QOI. QOI is a "Quite OK Image format", which aims for fast encoding and decoding of images, while providing a file size similar to PNGs. +In this exercise, we test if the image crate produces the same results when decoding QOI images as the [QOI reference C library](https://github.com/phoboslab/qoi). -### tweetnacl-bindgen - -Making rust bindings for the [tweetnacl](https://tweetnacl.cr.yp.to/) C library - -## Exercise: implement `crypto_hash_sha256_tweet` - -Below you find instructions for using bindgen and wrapping `crypto_hash_sha512_tweet`. Follow the instructions, then repeat the steps for `crypto_hash_sha256_tweet` - -## Instructions +The QOI C library is a header-only library, which means the function implementations are included within the header file instead of in a separate C file. We've added a separate C file which includes the header to make it easier to compile and include the library in our Rust program. +### Generating bindings Prerequisites: -- a C compiler is installed on the system -- bindgen, install with `cargo install bindgen-cli` +- A C compiler is installed on the system +- Bindgen, which can be installed with `cargo install bindgen-cli` -Steps +Steps: -1. Create the rust bindings: `bindgen tweetnacl.h -o src/bindings.rs` -2. Use `build.rs` to compile and link `tweetnacl.c`. Create `build.rs` and insert +1. Create the Rust bindings: `bindgen qoi.h -o src/bindings.rs` +2. Use a `build.rs` script to compile and link `qoi.h`. Create `build.rs` and insert ```rust fn main() { - cc::Build::new() - .file("tweetnacl.c") - .compile("tweetnacl"); // outputs `libtweetnacl.a` + cc::Build::new().file("qoi.c").compile("qoi"); // outputs `qoi.a` } ``` @@ -183,254 +181,146 @@ Steps ``` 3. Create `src/lib.rs` with the contents `pub mod bindings;`. This will make the `bindings` module available in `main.rs`. 4. Run `cargo check` to verify everything is compiling correctly. -5. By default building will generate a bunch of warnings. we can turn those off by replacing our build.rs with - ```rust - fn main() { - cc::Build::new() - .warnings(false) - .extra_warnings(false) - .file("tweetnacl.c") - .compile("tweetnacl"); // outputs `libtweetnacl.a` - } - ``` - - and adding this line at the top of `src/bindings.rs`: - ```rust - #![allow(non_upper_case_globals)] - ``` - -## Inspecting our bindings +### Inspecting our bindings -In the generated `bindings.rs` file we find this signature for the `crypto_hash_sha512_tweet` C function from tweetNaCl: +In the generated `bindings.rs` file we find this signature for the `qoi_read` C function from QOI: ```rust extern "C" { - pub fn crypto_hash_sha512_tweet( - arg1: *mut ::std::ffi::c_uchar, - arg2: *const ::std::ffi::c_uchar, - arg3: ::std::ffi::c_ulonglong, - ) -> ::std::ffi::c_int; + pub fn qoi_read( + filename: *const ::std::os::raw::c_char, + desc: *mut qoi_desc, + channels: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_void; } ``` -Some observations +Some observations: -- The definition is inside of an `extern "C"` block, and has no body. Therefore this function is marked as an extern, and rust expects it to be linked in. +- The definition is inside an `extern "C"` block, and has no body. Therefore, this function is marked as an extern, and Rust expects it to be linked in. - The function is marked `pub`, meaning we can import and use it in other modules (like `main.rs` in our case) -- We can deduce the behavior from the type signature: - * `arg1` is the output: a mutable pointer to a sequence of bytes - * `arg2` is the input: a constant pointer to a sequence of bytes - * `arg3` is a length (unclear of what) - * the return value is probably an error code -- These are raw C types, which makes it a hassle to call directly from rust. - -We will deal with the last point by writing some nice rust wrappers *around* the generated bindings. - -In rust we bundle a pointer to a sequence of elements and its length in a slice. We could write the signature of our own rust wrapper function as: +- We can deduce the behavior somewhat from the type signature: + * `filename` is a C string with the name of the QOI file we want to read + * `desc` describes some metadata about the image, the function will write to this `qoi_desc` struct. This struct was also generated by bindgen: + ```rust + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct qoi_desc { + pub width: ::std::os::raw::c_uint, + pub height: ::std::os::raw::c_uint, + pub channels: ::std::os::raw::c_uchar, + pub colorspace: ::std::os::raw::c_uchar, + } + ``` + * `channels` is the number of channels the image has: either 3 for RGB images, or 4 for RGBA images (which also have an alpha channel for transparency). For this exercise, we will assume the images have an alpha channel. + * The return value is a void pointer. If the function has successfully read the pixel data from a QOI image, then this pointer should point towards the pixel data. +- As the types are raw C types, it can be a hassle to call it directly from Rust. + +We will deal with the last point by writing a nice Rust wrapper *around* the generated bindings. + +### Writing our wrapper +To make the `qoi_read` function easier to use, we would like to write a wrapper that takes a path and returns an image buffer: ```rust -pub fn crypto_hash_sha512_tweet(out: &mut [u8], data: &[u8]) -> i32 { +fn read_qoi_image(filename: &Path) -> ImageBuffer, &[u8]> { todo!() } ``` -## Modelling with types - -But by looking at the tweetNaCl source code we can see that the contract is a bit stronger: - -- the output is always 64 bytes wide (64 * 8 = 512) -- we only ever return `0` - -```c -int crypto_hash(u8 *out,const u8 *m,u64 n) -{ - u8 h[64],x[256]; - u64 i,b = n; - - FOR(i,64) h[i] = iv[i]; - - crypto_hashblocks(h,m,n); - m += n; - n &= 127; - m -= n; - - FOR(i,256) x[i] = 0; - FOR(i,n) x[i] = m[i]; - x[n] = 128; - - n = 256-128*(n<112); - x[n-9] = b >> 61; - ts64(x+n-8,b<<3); - crypto_hashblocks(h,x,n); - - FOR(i,64) out[i] = h[i]; - - return 0; -} -``` - -The rust type system can model these invariants: We can explicitly make the output 64 elements long by using a reference to an array. Furthermore we can drop the return type if there is nothing useful to return. +To implement this wrapper, there are a couple of challenges that need to be solved: +- We need to turn the path into a C string. Hint: we can use `std::ffi::CString::new` to create a C string from a sequence of bytes, and the most convenient way to turn the path into bytes is to first get the `OsStr` from it. We can then pass the C string as a pointer. +- We need to provide a `qoi_desc`, this struct can be imported from the bindings. Pass a mutable reference to an instance of this struct to the function. +- After calling `qoi_read`, we need to turn the returned void pointer into an image buffer. + - First, we should check if the returned void pointer `is_null()`. If it is null, something has gone wrong with reading the image. + - Next, we need to determine the length of the returned pixel data. Assuming the image has an alpha channel, we have 4 bytes for every pixel in the image. The number of pixels in the image can be determined from the `qoi_desc` struct. + - Now we can turn our void pointer into a `&[u8]`. We can cast our void pointer `as *const u8` first. Next, we use `std::slice::from_raw_parts` with the previously calculated length. + - Finally, we can use `ImageBuffer::from_raw` to construct our image buffer. +To try out our wrapper, we can try to read a QOI image and export it as a PNG: ```rust -pub fn crypto_hash_sha512_tweet(out: &mut [u8; 64], data: &[u8]) { - todo!() +fn main() { + let image = read_qoi_image(Path::new("image.qoi")); + image.save("image.png").unwrap(); } ``` +If implemented correctly, this should produce a nice picture! -But even better, we can return the output array directly: - +Now that we can decode images using the QOI reference C library, we can test if the image crate produces the same results with the following unit test: ```rust -pub fn crypto_hash_sha512_tweet(data: &[u8]) -> [u8; 64] { - todo!() -} -``` - -The compiler will turn this signature into the one we had before under the hood. Returning the value is more idiomatic and convenient in rust, and with modern compilers there is no performance penalty. - -> In detail: The C ABI mandates that any return value larger than those that fit in a register (typically 128 bits nowadays) are allocated on the caller's stack. The first argument to the function is the pointer to write the result into. LLVM, the backend used by the rust compiler has specific optimizations to make sure the function result is written directly into this pointer. +#[cfg(test)] +mod tests { + use crate::read_qoi_image; + use std::path::Path; -## Writing our implementation + #[test] + fn test_qoi_read() { + let filename = "image.qoi"; + let image = image::open(filename).unwrap().into_rgba8(); + let my_image = read_qoi_image(Path::new(filename)); -Allright, with the signature worked out, we can write the actual implementation. + assert_eq!(image.width(), my_image.width()); + assert_eq!(image.height(), my_image.height()); -We can reach the bindings from `main.rs` with e.g. - -```rust -tweetnacl_bindgen::bindings::crypto_hash_sha512_tweet(a,b,c); -``` - -Here `tweetnacl_bindgen` is the name of the project, specified in the `package` section of the `Cargo.toml` - -```toml -[package] -name = "tweetnacl-bindgen" -``` - -Then `bindings` is the module name (the file `src/bindings.rs` is implicitly also a module) and finally `crypto_hash_sha512_tweet` is the function name from the original C library. - -On to the implmentation. Extern functions are considered unsafe in rust, so we will need an unsafe block to call ours. - -```rust -pub fn crypto_hash_sha512_tweet(data: &[u8]) -> [u8; 64] { - unsafe { - tweetnacl_bindgen::bindings::crypto_hash_sha512_tweet( - todo!(), - todo!(), - todo!(), - ); + assert!(image.pixels().eq(my_image.pixels())); } } ``` - -Next we can pass our argument: we turn the slice into a pointer with `.as_ptr()`, and get the length with `len()`. The length needs to be cast to the right type. In this case we can use `as _` where rust will infer the right type to cast to. - -```rust -pub fn crypto_hash_sha512_tweet(data: &[u8]) -> [u8; 64] { - unsafe { - tweetnacl_bindgen::bindings::crypto_hash_sha512_tweet( - todo!(), - data.as_ptr(), - data.len() as _, - ); - } -} +If you add this test to `main.rs` and run it with `cargo test` we should see: ``` - -Next we create an array for the return value, pass a mutable pointer to this memory to our extern functin, and return the array. - -```rust -pub fn crypto_hash_sha512_tweet(data: &[u8]) -> [u8; 64] { - let mut result = [ 0; 64 ]; - - unsafe { - tweetnacl_bindgen::bindings::crypto_hash_sha512_tweet( - &mut result as *mut _, - data.as_ptr(), - data.len() as _, - ); - } - - result -} +running 1 test +test tests::test_qoi_read ... ok ``` -And we're done: an idiomatic rust wrapper around the `crypto_hash_sha512_tweet`! - -## Uninitialized memory +### Freeing the pixel data +When working with data from C, we are responsible for deallocating the memory once we are done using it. Some C libraries might provide a separate function to clean up data structures. For QOI, we instead have to call `libc::free` to free the memory, as indicated by the documentation of the `qoi_read` function: +> The returned pixel data should be free()d after use. -There is one more trick: our current function initializes and zeroes out the memory for `result`. That is wasteful because the extern function will overwrite these zeroes. Because the extern function is linked in, the compiler likely does not have enough information to optimize the zeroing out away. - -The solution is `MaybeUninit`: - -```rust -use std::mem::MaybeUninit; - -pub fn crypto_hash_sha512_tweet(data: &[u8]) -> [u8; 64] { - let mut result : MaybeUninit<[u8; 64]> = MaybeUninit::uninit(); - - unsafe { - tweetnacl_bindgen::bindings::crypto_hash_sha512_tweet( - result.as_mut_ptr() as *mut _, - data.as_ptr(), - data.len() as _, - ); +To make sure someone using our wrapper does not forget to free the memory, we can implement the `Drop` trait to automatically call `libc::free` when the variable goes out of scope. +- First, create a wrapper `struct MyImage<'a>(ImageBuffer, &'a [u8]>);`, which holds the image buffer. +- Next, implement the `Drop` trait for `MyImage` to free the memory (we should retrieve the pointer from the image buffer and cast it back to a void pointer): + ```rust + impl Drop for MyImage<'_> { + fn drop(&mut self) { + todo!(); // call libc::free here using a pointer to the image buffer + } + } + ``` +- To make this `MyImage` wrapper more convenient to use, we can also implement the `Deref` trait to allow us to directly call the methods from the internal image buffer on it: + ```rust + impl<'a> Deref for MyImage<'a> { + type Target = ImageBuffer, &'a [u8]>; - result.assume_init() + fn deref(&self) -> &Self::Target { + &self.0 + } } -} -``` + ``` +- Now update the `read_qoi_image` function to return an instance of `MyImage`. -The `std::mem::MaybeUninit` type is an abstraction for uninitialized memory. The `.uninit()` method gives a chunk of uninitialized memory big enough to store a value of the desired type (in our case `[u8; 64]` will be inferred). +### Uninitialized memory +There is one more trick: our current function initializes the `qoi_desc` struct with zeros (or whatever values you put there while creating an instance of the struct). This is wasteful because the extern function will overwrite these values. Because the extern function is linked in, the compiler likely does not have enough information to optimize this. -We can look at the LLVM IR to verify that 1) the initialization with zeroes is not optimized away and 2) using MaybeUninit does not initialize the array. +For a relatively small struct such as `qoi_desc`, this is not much of a problem. However, for larger structures or big arrays, this can make a serious impact on performance. -Below is a call site of our `crypto_hash_sha512_tweet` function that zeroes out the memory. Indeed, we see a `memset` that sets all the bytes to 0. (also not that our wrapper function actually got inlined) +If we look at the LLVM IR, the intermediate representation which is generated and optimized before it gets turned into assembly code, we can see that it did not optimize away the initialization of the struct with values. Here we see it uses `memset` to initialize the `desc` with zeros before calling `qoi_read`: ```llvm -%result.i = alloca <64 x i8>, align 1 -%0 = getelementptr inbounds <64 x i8>, <64 x i8>* %result.i, i64 0, i64 0 -call void @llvm.memset.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(64) %0, i8 0, i64 64, i1 false), !alias.scope !8, !noalias !11 -%_2.i = call i32 @bindings::crypto_hash_sha512_tweet(i8* nonnull %0, i8* nonnull "foobarbaz", i64 9) +call void @llvm.memset.p0.i64(ptr noundef nonnull align 4 dereferenceable(10) %desc.i, i8 0, i64 10, i1 false), !noalias !142 +%pointer.i = call noundef ptr @qoi_read(ptr noundef nonnull %t.0.i.i, ptr noundef nonnull %desc.i, i32 noundef 4) #17, !noalias !142 ``` -In constrast, the version with `MaybeUninit` just calls our extern function without touching the memory at all: -```llvm -%result.i = alloca <64 x i8>, align 1 -%0 = getelementptr inbounds <64 x i8>, <64 x i8>* %result.i, i64 0, i64 0 - -%_3.i = call i32 @bindings::crypto_hash_sha512_tweet(i8* nonnull %0, i8* nonnull "foobarbaz", i64 9), !noalias !6 -``` -
-Full LLVM IR -

+(The LLVM IR can be generated using `cargo rustc --bin qoi-bindgen --release -- --emit=llvm-ir`) -```llvm -define i8 @call_with_maybeuninit() unnamed_addr #1 personality i32 (i32, i32, i64, %"unwind::libunwind::_Unwind_Exception"*, %"unwind::libunwind::_Unwind_Context"*)* @rust_eh_personality { -start: - %result.i = alloca <64 x i8>, align 1 - %0 = getelementptr inbounds <64 x i8>, <64 x i8>* %result.i, i64 0, i64 0 - call void @llvm.lifetime.start.p0i8(i64 64, i8* nonnull %0), !noalias !2 - %_3.i = call i32 @crypto_hash_sha512_tweet(i8* nonnull %0, i8* nonnull getelementptr inbounds (<{ [9 x i8] }>, <{ [9 x i8] }>* @alloc1, i64 0, i32 0, i64 0), i64 9), !noalias !6 - %1 = load <64 x i8>, <64 x i8>* %result.i, align 1, !noalias !7 - call void @llvm.lifetime.end.p0i8(i64 64, i8* nonnull %0), !noalias !2 - %2 = call i8 @llvm.vector.reduce.add.v64i8(<64 x i8> %1) - ret i8 %2 -} +The solution is to use `std::mem::MaybeUninit`: -define i8 @call_without_maybeuninit() unnamed_addr #1 personality i32 (i32, i32, i64, %"unwind::libunwind::_Unwind_Exception"*, %"unwind::libunwind::_Unwind_Context"*)* @rust_eh_personality { -start: - %_4 = alloca <64 x i8>, align 1 - %0 = getelementptr inbounds <64 x i8>, <64 x i8>* %_4, i64 0, i64 0 - call void @llvm.lifetime.start.p0i8(i64 64, i8* nonnull %0) - call void @llvm.memset.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(64) %0, i8 0, i64 64, i1 false), !alias.scope !8, !noalias !11 - %_2.i = call i32 @crypto_hash_sha512_tweet(i8* nonnull %0, i8* nonnull getelementptr inbounds (<{ [9 x i8] }>, <{ [9 x i8] }>* @alloc1, i64 0, i32 0, i64 0), i64 9) - %1 = load <64 x i8>, <64 x i8>* %_4, align 1 - %2 = call i8 @llvm.vector.reduce.add.v64i8(<64 x i8> %1) - call void @llvm.lifetime.end.p0i8(i64 64, i8* nonnull %0) - ret i8 %2 -} +```rust +let mut desc = MaybeUninit::uninit(); +let pointer = unsafe { qoi_read(filename.as_ptr(), desc.as_mut_ptr(), 4) }; +let desc = unsafe { desc.assume_init() }; ``` -

-
+The `MaybeUninit` type is an abstraction for uninitialized memory. The `.uninit()` method gives a chunk of uninitialized memory big enough to store a value of the desired type (in our case `qoi_desc` will be inferred). + +### Conclusion +In this exercise we saw how we can generate bindings to a C library with bindgen. The generated bindings are a bit difficult to work with, as they are unsafe and rely on C types. We've discussed how we can create nice wrappers around the generated bindings to deal with all these C types and to make them safer to work with. diff --git a/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-qoi-bindgen/Cargo.lock b/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-qoi-bindgen/Cargo.lock new file mode 100644 index 0000000..796df20 --- /dev/null +++ b/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-qoi-bindgen/Cargo.lock @@ -0,0 +1,1009 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "aligned-vec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" + +[[package]] +name = "anyhow" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" + +[[package]] +name = "arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" + +[[package]] +name = "arg_enum_proc_macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "av1-grain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" +dependencies = [ + "anyhow", + "arrayvec", + "log", + "nom", + "num-rational", + "v_frame", +] + +[[package]] +name = "avif-serialize" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e335041290c43101ca215eed6f43ec437eb5a42125573f600fc3fa42b9bddd62" +dependencies = [ + "arrayvec", +] + +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitstream-io" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2" + +[[package]] +name = "built" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c360505aed52b7ec96a3636c3f039d99103c37d1d9b4f7a8c743d3ea9ffcd03b" + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "bytemuck" +version = "1.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + +[[package]] +name = "cc" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cfg-expr" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +dependencies = [ + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "exr" +version = "1.73.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83197f59927b46c04a183a619b7c29df34e63e63c7869320862268c0ef687e0" +dependencies = [ + "bit_field", + "half", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + +[[package]] +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "flate2" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gif" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "image" +version = "0.25.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd6f44aed642f18953a158afeb30206f4d50da59fbc66ecb53c66488de73563b" +dependencies = [ + "bytemuck", + "byteorder-lite", + "color_quant", + "exr", + "gif", + "image-webp", + "num-traits", + "png", + "qoi", + "ravif", + "rayon", + "rgb", + "tiff", + "zune-core", + "zune-jpeg", +] + +[[package]] +name = "image-webp" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e031e8e3d94711a9ccb5d6ea357439ef3dcbed361798bd4071dc4d9793fbe22f" +dependencies = [ + "byteorder-lite", + "quick-error", +] + +[[package]] +name = "imgref" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408" + +[[package]] +name = "indexmap" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "interpolate_name" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" + +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + +[[package]] +name = "libc" +version = "0.2.167" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" + +[[package]] +name = "libfuzzer-sys" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b9569d2f74e257076d8c6bfa73fb505b46b851e51ddaecc825944aa3bed17fa" +dependencies = [ + "arbitrary", + "cc", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "loop9" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" +dependencies = [ + "imgref", +] + +[[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", + "rayon", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "noop_proc_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[package]] +name = "png" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52f9d46a34a05a6a57566bc2bfae066ef07585a6e3fa30fbbdff5936380623f0" +dependencies = [ + "bitflags", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "profiling" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" +dependencies = [ + "profiling-procmacros", +] + +[[package]] +name = "profiling-procmacros" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "qoi-bindgen" +version = "0.1.0" +dependencies = [ + "image", + "libc", +] + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rav1e" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" +dependencies = [ + "arbitrary", + "arg_enum_proc_macro", + "arrayvec", + "av1-grain", + "bitstream-io", + "built", + "cfg-if", + "interpolate_name", + "itertools", + "libc", + "libfuzzer-sys", + "log", + "maybe-rayon", + "new_debug_unreachable", + "noop_proc_macro", + "num-derive", + "num-traits", + "once_cell", + "paste", + "profiling", + "rand", + "rand_chacha", + "simd_helpers", + "system-deps", + "thiserror", + "v_frame", + "wasm-bindgen", +] + +[[package]] +name = "ravif" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2413fd96bd0ea5cdeeb37eaf446a22e6ed7b981d792828721e74ded1980a45c6" +dependencies = [ + "avif-serialize", + "imgref", + "loop9", + "quick-error", + "rav1e", + "rayon", + "rgb", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "rgb" +version = "0.8.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" + +[[package]] +name = "serde" +version = "1.0.215" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.215" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "simd_helpers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" +dependencies = [ + "quote", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "syn" +version = "2.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "system-deps" +version = "6.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tiff" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "v_frame" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b" +dependencies = [ + "aligned-vec", + "num-traits", + "wasm-bindgen", +] + +[[package]] +name = "version-compare" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d15e63b4482863c109d70a7b8706c1e364eb6ea449b201a76c5b89cedcec2d5c" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d36ef12e3aaca16ddd3f67922bc63e48e953f126de60bd33ccc0101ef9998cd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "705440e08b42d3e4b36de7d66c944be628d579796b8090bfa3471478a2260051" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98c9ae5a76e46f4deecd0f0255cc223cfa18dc9b261213b8aa0c7b36f61b3f1d" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49" + +[[package]] +name = "weezl" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" + +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zune-core" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" + +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "zune-jpeg" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16099418600b4d8f028622f73ff6e3deaabdff330fb9a2a131dea781ee8b0768" +dependencies = [ + "zune-core", +] diff --git a/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-qoi-bindgen/Cargo.toml b/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-qoi-bindgen/Cargo.toml new file mode 100644 index 0000000..e570fa0 --- /dev/null +++ b/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-qoi-bindgen/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "qoi-bindgen" +version = "0.1.0" +edition = "2021" + +[dependencies] +image = "0.25.5" +libc = "0.2.167" diff --git a/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-qoi-bindgen/image.qoi b/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-qoi-bindgen/image.qoi new file mode 100644 index 0000000000000000000000000000000000000000..2a7b5c3059bfb98bad7e2295d90e864113e39b81 GIT binary patch literal 237804 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®^yC~nfBTM|w8en8JDu)o+&i^A8P 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%0Dyk<>CF^ZF$PzO51B9n*9(7YZKkuI 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

0Q<&1;0)w*EQxEvm|^l=OtlW8uG6&3QC0D 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"^6>w`G!hb1$0h$PL{wf0Ie^L)3! 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 CdH`Jj literal 0 HcmV?d00001 diff --git a/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-qoi-bindgen/qoi.c b/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-qoi-bindgen/qoi.c new file mode 100644 index 0000000..d5962fc --- /dev/null +++ b/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-qoi-bindgen/qoi.c @@ -0,0 +1,2 @@ +#define QOI_IMPLEMENTATION +#include "qoi.h" diff --git a/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-qoi-bindgen/qoi.h b/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-qoi-bindgen/qoi.h new file mode 100644 index 0000000..f2800b0 --- /dev/null +++ b/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-qoi-bindgen/qoi.h @@ -0,0 +1,649 @@ +/* + +Copyright (c) 2021, Dominic Szablewski - https://phoboslab.org +SPDX-License-Identifier: MIT + + +QOI - The "Quite OK Image" format for fast, lossless image compression + +-- About + +QOI encodes and decodes images in a lossless format. Compared to stb_image and +stb_image_write QOI offers 20x-50x faster encoding, 3x-4x faster decoding and +20% better compression. + + +-- Synopsis + +// Define `QOI_IMPLEMENTATION` in *one* C/C++ file before including this +// library to create the implementation. + +#define QOI_IMPLEMENTATION +#include "qoi.h" + +// Encode and store an RGBA buffer to the file system. The qoi_desc describes +// the input pixel data. +qoi_write("image_new.qoi", rgba_pixels, &(qoi_desc){ + .width = 1920, + .height = 1080, + .channels = 4, + .colorspace = QOI_SRGB +}); + +// Load and decode a QOI image from the file system into a 32bbp RGBA buffer. +// The qoi_desc struct will be filled with the width, height, number of channels +// and colorspace read from the file header. +qoi_desc desc; +void *rgba_pixels = qoi_read("image.qoi", &desc, 4); + + + +-- Documentation + +This library provides the following functions; +- qoi_read -- read and decode a QOI file +- qoi_decode -- decode the raw bytes of a QOI image from memory +- qoi_write -- encode and write a QOI file +- qoi_encode -- encode an rgba buffer into a QOI image in memory + +See the function declaration below for the signature and more information. + +If you don't want/need the qoi_read and qoi_write functions, you can define +QOI_NO_STDIO before including this library. + +This library uses malloc() and free(). To supply your own malloc implementation +you can define QOI_MALLOC and QOI_FREE before including this library. + +This library uses memset() to zero-initialize the index. To supply your own +implementation you can define QOI_ZEROARR before including this library. + + +-- Data Format + +A QOI file has a 14 byte header, followed by any number of data "chunks" and an +8-byte end marker. + +struct qoi_header_t { + char magic[4]; // magic bytes "qoif" + uint32_t width; // image width in pixels (BE) + uint32_t height; // image height in pixels (BE) + uint8_t channels; // 3 = RGB, 4 = RGBA + uint8_t colorspace; // 0 = sRGB with linear alpha, 1 = all channels linear +}; + +Images are encoded row by row, left to right, top to bottom. The decoder and +encoder start with {r: 0, g: 0, b: 0, a: 255} as the previous pixel value. An +image is complete when all pixels specified by width * height have been covered. + +Pixels are encoded as + - a run of the previous pixel + - an index into an array of previously seen pixels + - a difference to the previous pixel value in r,g,b + - full r,g,b or r,g,b,a values + +The color channels are assumed to not be premultiplied with the alpha channel +("un-premultiplied alpha"). + +A running array[64] (zero-initialized) of previously seen pixel values is +maintained by the encoder and decoder. Each pixel that is seen by the encoder +and decoder is put into this array at the position formed by a hash function of +the color value. In the encoder, if the pixel value at the index matches the +current pixel, this index position is written to the stream as QOI_OP_INDEX. +The hash function for the index is: + + index_position = (r * 3 + g * 5 + b * 7 + a * 11) % 64 + +Each chunk starts with a 2- or 8-bit tag, followed by a number of data bits. The +bit length of chunks is divisible by 8 - i.e. all chunks are byte aligned. All +values encoded in these data bits have the most significant bit on the left. + +The 8-bit tags have precedence over the 2-bit tags. A decoder must check for the +presence of an 8-bit tag first. + +The byte stream's end is marked with 7 0x00 bytes followed a single 0x01 byte. + + +The possible chunks are: + + +.- QOI_OP_INDEX ----------. +| Byte[0] | +| 7 6 5 4 3 2 1 0 | +|-------+-----------------| +| 0 0 | index | +`-------------------------` +2-bit tag b00 +6-bit index into the color index array: 0..63 + +A valid encoder must not issue 2 or more consecutive QOI_OP_INDEX chunks to the +same index. QOI_OP_RUN should be used instead. + + +.- QOI_OP_DIFF -----------. +| Byte[0] | +| 7 6 5 4 3 2 1 0 | +|-------+-----+-----+-----| +| 0 1 | dr | dg | db | +`-------------------------` +2-bit tag b01 +2-bit red channel difference from the previous pixel between -2..1 +2-bit green channel difference from the previous pixel between -2..1 +2-bit blue channel difference from the previous pixel between -2..1 + +The difference to the current channel values are using a wraparound operation, +so "1 - 2" will result in 255, while "255 + 1" will result in 0. + +Values are stored as unsigned integers with a bias of 2. E.g. -2 is stored as +0 (b00). 1 is stored as 3 (b11). + +The alpha value remains unchanged from the previous pixel. + + +.- QOI_OP_LUMA -------------------------------------. +| Byte[0] | Byte[1] | +| 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 | +|-------+-----------------+-------------+-----------| +| 1 0 | green diff | dr - dg | db - dg | +`---------------------------------------------------` +2-bit tag b10 +6-bit green channel difference from the previous pixel -32..31 +4-bit red channel difference minus green channel difference -8..7 +4-bit blue channel difference minus green channel difference -8..7 + +The green channel is used to indicate the general direction of change and is +encoded in 6 bits. The red and blue channels (dr and db) base their diffs off +of the green channel difference and are encoded in 4 bits. I.e.: + dr_dg = (cur_px.r - prev_px.r) - (cur_px.g - prev_px.g) + db_dg = (cur_px.b - prev_px.b) - (cur_px.g - prev_px.g) + +The difference to the current channel values are using a wraparound operation, +so "10 - 13" will result in 253, while "250 + 7" will result in 1. + +Values are stored as unsigned integers with a bias of 32 for the green channel +and a bias of 8 for the red and blue channel. + +The alpha value remains unchanged from the previous pixel. + + +.- QOI_OP_RUN ------------. +| Byte[0] | +| 7 6 5 4 3 2 1 0 | +|-------+-----------------| +| 1 1 | run | +`-------------------------` +2-bit tag b11 +6-bit run-length repeating the previous pixel: 1..62 + +The run-length is stored with a bias of -1. Note that the run-lengths 63 and 64 +(b111110 and b111111) are illegal as they are occupied by the QOI_OP_RGB and +QOI_OP_RGBA tags. + + +.- QOI_OP_RGB ------------------------------------------. +| Byte[0] | Byte[1] | Byte[2] | Byte[3] | +| 7 6 5 4 3 2 1 0 | 7 .. 0 | 7 .. 0 | 7 .. 0 | +|-------------------------+---------+---------+---------| +| 1 1 1 1 1 1 1 0 | red | green | blue | +`-------------------------------------------------------` +8-bit tag b11111110 +8-bit red channel value +8-bit green channel value +8-bit blue channel value + +The alpha value remains unchanged from the previous pixel. + + +.- QOI_OP_RGBA ---------------------------------------------------. +| Byte[0] | Byte[1] | Byte[2] | Byte[3] | Byte[4] | +| 7 6 5 4 3 2 1 0 | 7 .. 0 | 7 .. 0 | 7 .. 0 | 7 .. 0 | +|-------------------------+---------+---------+---------+---------| +| 1 1 1 1 1 1 1 1 | red | green | blue | alpha | +`-----------------------------------------------------------------` +8-bit tag b11111111 +8-bit red channel value +8-bit green channel value +8-bit blue channel value +8-bit alpha channel value + +*/ + + +/* ----------------------------------------------------------------------------- +Header - Public functions */ + +#ifndef QOI_H +#define QOI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* A pointer to a qoi_desc struct has to be supplied to all of qoi's functions. +It describes either the input format (for qoi_write and qoi_encode), or is +filled with the description read from the file header (for qoi_read and +qoi_decode). + +The colorspace in this qoi_desc is an enum where + 0 = sRGB, i.e. gamma scaled RGB channels and a linear alpha channel + 1 = all channels are linear +You may use the constants QOI_SRGB or QOI_LINEAR. The colorspace is purely +informative. It will be saved to the file header, but does not affect +how chunks are en-/decoded. */ + +#define QOI_SRGB 0 +#define QOI_LINEAR 1 + +typedef struct { + unsigned int width; + unsigned int height; + unsigned char channels; + unsigned char colorspace; +} qoi_desc; + +#ifndef QOI_NO_STDIO + +/* Encode raw RGB or RGBA pixels into a QOI image and write it to the file +system. The qoi_desc struct must be filled with the image width, height, +number of channels (3 = RGB, 4 = RGBA) and the colorspace. + +The function returns 0 on failure (invalid parameters, or fopen or malloc +failed) or the number of bytes written on success. */ + +int qoi_write(const char *filename, const void *data, const qoi_desc *desc); + + +/* Read and decode a QOI image from the file system. If channels is 0, the +number of channels from the file header is used. If channels is 3 or 4 the +output format will be forced into this number of channels. + +The function either returns NULL on failure (invalid data, or malloc or fopen +failed) or a pointer to the decoded pixels. On success, the qoi_desc struct +will be filled with the description from the file header. + +The returned pixel data should be free()d after use. */ + +void *qoi_read(const char *filename, qoi_desc *desc, int channels); + +#endif /* QOI_NO_STDIO */ + + +/* Encode raw RGB or RGBA pixels into a QOI image in memory. + +The function either returns NULL on failure (invalid parameters or malloc +failed) or a pointer to the encoded data on success. On success the out_len +is set to the size in bytes of the encoded data. + +The returned qoi data should be free()d after use. */ + +void *qoi_encode(const void *data, const qoi_desc *desc, int *out_len); + + +/* Decode a QOI image from memory. + +The function either returns NULL on failure (invalid parameters or malloc +failed) or a pointer to the decoded pixels. On success, the qoi_desc struct +is filled with the description from the file header. + +The returned pixel data should be free()d after use. */ + +void *qoi_decode(const void *data, int size, qoi_desc *desc, int channels); + + +#ifdef __cplusplus +} +#endif +#endif /* QOI_H */ + + +/* ----------------------------------------------------------------------------- +Implementation */ + +#ifdef QOI_IMPLEMENTATION +#include +#include + +#ifndef QOI_MALLOC + #define QOI_MALLOC(sz) malloc(sz) + #define QOI_FREE(p) free(p) +#endif +#ifndef QOI_ZEROARR + #define QOI_ZEROARR(a) memset((a),0,sizeof(a)) +#endif + +#define QOI_OP_INDEX 0x00 /* 00xxxxxx */ +#define QOI_OP_DIFF 0x40 /* 01xxxxxx */ +#define QOI_OP_LUMA 0x80 /* 10xxxxxx */ +#define QOI_OP_RUN 0xc0 /* 11xxxxxx */ +#define QOI_OP_RGB 0xfe /* 11111110 */ +#define QOI_OP_RGBA 0xff /* 11111111 */ + +#define QOI_MASK_2 0xc0 /* 11000000 */ + +#define QOI_COLOR_HASH(C) (C.rgba.r*3 + C.rgba.g*5 + C.rgba.b*7 + C.rgba.a*11) +#define QOI_MAGIC \ + (((unsigned int)'q') << 24 | ((unsigned int)'o') << 16 | \ + ((unsigned int)'i') << 8 | ((unsigned int)'f')) +#define QOI_HEADER_SIZE 14 + +/* 2GB is the max file size that this implementation can safely handle. We guard +against anything larger than that, assuming the worst case with 5 bytes per +pixel, rounded down to a nice clean value. 400 million pixels ought to be +enough for anybody. */ +#define QOI_PIXELS_MAX ((unsigned int)400000000) + +typedef union { + struct { unsigned char r, g, b, a; } rgba; + unsigned int v; +} qoi_rgba_t; + +static const unsigned char qoi_padding[8] = {0,0,0,0,0,0,0,1}; + +static void qoi_write_32(unsigned char *bytes, int *p, unsigned int v) { + bytes[(*p)++] = (0xff000000 & v) >> 24; + bytes[(*p)++] = (0x00ff0000 & v) >> 16; + bytes[(*p)++] = (0x0000ff00 & v) >> 8; + bytes[(*p)++] = (0x000000ff & v); +} + +static unsigned int qoi_read_32(const unsigned char *bytes, int *p) { + unsigned int a = bytes[(*p)++]; + unsigned int b = bytes[(*p)++]; + unsigned int c = bytes[(*p)++]; + unsigned int d = bytes[(*p)++]; + return a << 24 | b << 16 | c << 8 | d; +} + +void *qoi_encode(const void *data, const qoi_desc *desc, int *out_len) { + int i, max_size, p, run; + int px_len, px_end, px_pos, channels; + unsigned char *bytes; + const unsigned char *pixels; + qoi_rgba_t index[64]; + qoi_rgba_t px, px_prev; + + if ( + data == NULL || out_len == NULL || desc == NULL || + desc->width == 0 || desc->height == 0 || + desc->channels < 3 || desc->channels > 4 || + desc->colorspace > 1 || + desc->height >= QOI_PIXELS_MAX / desc->width + ) { + return NULL; + } + + max_size = + desc->width * desc->height * (desc->channels + 1) + + QOI_HEADER_SIZE + sizeof(qoi_padding); + + p = 0; + bytes = (unsigned char *) QOI_MALLOC(max_size); + if (!bytes) { + return NULL; + } + + qoi_write_32(bytes, &p, QOI_MAGIC); + qoi_write_32(bytes, &p, desc->width); + qoi_write_32(bytes, &p, desc->height); + bytes[p++] = desc->channels; + bytes[p++] = desc->colorspace; + + + pixels = (const unsigned char *)data; + + QOI_ZEROARR(index); + + run = 0; + px_prev.rgba.r = 0; + px_prev.rgba.g = 0; + px_prev.rgba.b = 0; + px_prev.rgba.a = 255; + px = px_prev; + + px_len = desc->width * desc->height * desc->channels; + px_end = px_len - desc->channels; + channels = desc->channels; + + for (px_pos = 0; px_pos < px_len; px_pos += channels) { + px.rgba.r = pixels[px_pos + 0]; + px.rgba.g = pixels[px_pos + 1]; + px.rgba.b = pixels[px_pos + 2]; + + if (channels == 4) { + px.rgba.a = pixels[px_pos + 3]; + } + + if (px.v == px_prev.v) { + run++; + if (run == 62 || px_pos == px_end) { + bytes[p++] = QOI_OP_RUN | (run - 1); + run = 0; + } + } + else { + int index_pos; + + if (run > 0) { + bytes[p++] = QOI_OP_RUN | (run - 1); + run = 0; + } + + index_pos = QOI_COLOR_HASH(px) % 64; + + if (index[index_pos].v == px.v) { + bytes[p++] = QOI_OP_INDEX | index_pos; + } + else { + index[index_pos] = px; + + if (px.rgba.a == px_prev.rgba.a) { + signed char vr = px.rgba.r - px_prev.rgba.r; + signed char vg = px.rgba.g - px_prev.rgba.g; + signed char vb = px.rgba.b - px_prev.rgba.b; + + signed char vg_r = vr - vg; + signed char vg_b = vb - vg; + + if ( + vr > -3 && vr < 2 && + vg > -3 && vg < 2 && + vb > -3 && vb < 2 + ) { + bytes[p++] = QOI_OP_DIFF | (vr + 2) << 4 | (vg + 2) << 2 | (vb + 2); + } + else if ( + vg_r > -9 && vg_r < 8 && + vg > -33 && vg < 32 && + vg_b > -9 && vg_b < 8 + ) { + bytes[p++] = QOI_OP_LUMA | (vg + 32); + bytes[p++] = (vg_r + 8) << 4 | (vg_b + 8); + } + else { + bytes[p++] = QOI_OP_RGB; + bytes[p++] = px.rgba.r; + bytes[p++] = px.rgba.g; + bytes[p++] = px.rgba.b; + } + } + else { + bytes[p++] = QOI_OP_RGBA; + bytes[p++] = px.rgba.r; + bytes[p++] = px.rgba.g; + bytes[p++] = px.rgba.b; + bytes[p++] = px.rgba.a; + } + } + } + px_prev = px; + } + + for (i = 0; i < (int)sizeof(qoi_padding); i++) { + bytes[p++] = qoi_padding[i]; + } + + *out_len = p; + return bytes; +} + +void *qoi_decode(const void *data, int size, qoi_desc *desc, int channels) { + const unsigned char *bytes; + unsigned int header_magic; + unsigned char *pixels; + qoi_rgba_t index[64]; + qoi_rgba_t px; + int px_len, chunks_len, px_pos; + int p = 0, run = 0; + + if ( + data == NULL || desc == NULL || + (channels != 0 && channels != 3 && channels != 4) || + size < QOI_HEADER_SIZE + (int)sizeof(qoi_padding) + ) { + return NULL; + } + + bytes = (const unsigned char *)data; + + header_magic = qoi_read_32(bytes, &p); + desc->width = qoi_read_32(bytes, &p); + desc->height = qoi_read_32(bytes, &p); + desc->channels = bytes[p++]; + desc->colorspace = bytes[p++]; + + if ( + desc->width == 0 || desc->height == 0 || + desc->channels < 3 || desc->channels > 4 || + desc->colorspace > 1 || + header_magic != QOI_MAGIC || + desc->height >= QOI_PIXELS_MAX / desc->width + ) { + return NULL; + } + + if (channels == 0) { + channels = desc->channels; + } + + px_len = desc->width * desc->height * channels; + pixels = (unsigned char *) QOI_MALLOC(px_len); + if (!pixels) { + return NULL; + } + + QOI_ZEROARR(index); + px.rgba.r = 0; + px.rgba.g = 0; + px.rgba.b = 0; + px.rgba.a = 255; + + chunks_len = size - (int)sizeof(qoi_padding); + for (px_pos = 0; px_pos < px_len; px_pos += channels) { + if (run > 0) { + run--; + } + else if (p < chunks_len) { + int b1 = bytes[p++]; + + if (b1 == QOI_OP_RGB) { + px.rgba.r = bytes[p++]; + px.rgba.g = bytes[p++]; + px.rgba.b = bytes[p++]; + } + else if (b1 == QOI_OP_RGBA) { + px.rgba.r = bytes[p++]; + px.rgba.g = bytes[p++]; + px.rgba.b = bytes[p++]; + px.rgba.a = bytes[p++]; + } + else if ((b1 & QOI_MASK_2) == QOI_OP_INDEX) { + px = index[b1]; + } + else if ((b1 & QOI_MASK_2) == QOI_OP_DIFF) { + px.rgba.r += ((b1 >> 4) & 0x03) - 2; + px.rgba.g += ((b1 >> 2) & 0x03) - 2; + px.rgba.b += ( b1 & 0x03) - 2; + } + else if ((b1 & QOI_MASK_2) == QOI_OP_LUMA) { + int b2 = bytes[p++]; + int vg = (b1 & 0x3f) - 32; + px.rgba.r += vg - 8 + ((b2 >> 4) & 0x0f); + px.rgba.g += vg; + px.rgba.b += vg - 8 + (b2 & 0x0f); + } + else if ((b1 & QOI_MASK_2) == QOI_OP_RUN) { + run = (b1 & 0x3f); + } + + index[QOI_COLOR_HASH(px) % 64] = px; + } + + pixels[px_pos + 0] = px.rgba.r; + pixels[px_pos + 1] = px.rgba.g; + pixels[px_pos + 2] = px.rgba.b; + + if (channels == 4) { + pixels[px_pos + 3] = px.rgba.a; + } + } + + return pixels; +} + +#ifndef QOI_NO_STDIO +#include + +int qoi_write(const char *filename, const void *data, const qoi_desc *desc) { + FILE *f = fopen(filename, "wb"); + int size, err; + void *encoded; + + if (!f) { + return 0; + } + + encoded = qoi_encode(data, desc, &size); + if (!encoded) { + fclose(f); + return 0; + } + + fwrite(encoded, 1, size, f); + fflush(f); + err = ferror(f); + fclose(f); + + QOI_FREE(encoded); + return err ? 0 : size; +} + +void *qoi_read(const char *filename, qoi_desc *desc, int channels) { + FILE *f = fopen(filename, "rb"); + int size, bytes_read; + void *pixels, *data; + + if (!f) { + return NULL; + } + + fseek(f, 0, SEEK_END); + size = ftell(f); + if (size <= 0 || fseek(f, 0, SEEK_SET) != 0) { + fclose(f); + return NULL; + } + + data = QOI_MALLOC(size); + if (!data) { + fclose(f); + return NULL; + } + + bytes_read = fread(data, 1, size, f); + fclose(f); + pixels = (bytes_read != size) ? NULL : qoi_decode(data, bytes_read, desc, channels); + QOI_FREE(data); + return pixels; +} + +#endif /* QOI_NO_STDIO */ +#endif /* QOI_IMPLEMENTATION */ diff --git a/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-qoi-bindgen/src/main.rs b/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-qoi-bindgen/src/main.rs new file mode 100644 index 0000000..54568cf --- /dev/null +++ b/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-qoi-bindgen/src/main.rs @@ -0,0 +1,11 @@ +use image::{ImageBuffer, Rgba}; +use std::path::Path; + +fn read_qoi_image(_filename: &Path) -> ImageBuffer, &[u8]> { + todo!() +} + +fn main() { + let image = read_qoi_image(Path::new("image.qoi")); + image.save("image.png").unwrap(); +} diff --git a/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/Cargo.lock b/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/Cargo.lock deleted file mode 100644 index d7218be..0000000 --- a/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "tweetnacl-bindgen" -version = "0.1.0" diff --git a/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/Cargo.toml b/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/Cargo.toml deleted file mode 100644 index 4a44d82..0000000 --- a/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "tweetnacl-bindgen" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] diff --git a/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/src/lib.rs b/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/src/lib.rs deleted file mode 100644 index 90c70dc..0000000 --- a/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/src/lib.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod bindings; diff --git a/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/src/main.rs b/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/src/main.rs deleted file mode 100644 index e7a11a9..0000000 --- a/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -} diff --git a/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/tweetnacl.c b/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/tweetnacl.c deleted file mode 100644 index 5bed5d6..0000000 --- a/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/tweetnacl.c +++ /dev/null @@ -1,784 +0,0 @@ -#include "tweetnacl.h" -#define FOR(i,n) for (i = 0;i < n;++i) -#define sv static void - -typedef unsigned char u8; -typedef unsigned long u32; -typedef unsigned long long u64; -typedef long long i64; -typedef i64 gf[16]; -extern void randombytes(u8 *,u64); - -static const u8 - _0[16], - _9[32] = {9}; -static const gf - gf0, - gf1 = {1}, - _121665 = {0xDB41,1}, - D = {0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203}, - D2 = {0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406}, - X = {0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169}, - Y = {0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666}, - I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83}; - -static u32 L32(u32 x,int c) { return (x << c) | (x >> (32 - c)); } - -static u32 ld32(const u8 *x) -{ - u32 u = x[3]; - u = (u<<8)|x[2]; - u = (u<<8)|x[1]; - return (u<<8)|x[0]; -} - -static u64 dl64(const u8 *x) -{ - u64 i,u=0; - FOR(i,8) u=(u<<8)|x[i]; - return u; -} - -sv st32(u8 *x,u32 u) -{ - int i; - FOR(i,4) { x[i] = u; u >>= 8; } -} - -sv ts64(u8 *x,u64 u) -{ - int i; - for (i = 7;i >= 0;--i) { x[i] = u; u >>= 8; } -} - -static int vn(const u8 *x,const u8 *y,int n) -{ - u32 i,d = 0; - FOR(i,n) d |= x[i]^y[i]; - return (1 & ((d - 1) >> 8)) - 1; -} - -int crypto_verify_16(const u8 *x,const u8 *y) -{ - return vn(x,y,16); -} - -int crypto_verify_32(const u8 *x,const u8 *y) -{ - return vn(x,y,32); -} - -sv core(u8 *out,const u8 *in,const u8 *k,const u8 *c,int h) -{ - u32 w[16],x[16],y[16],t[4]; - int i,j,m; - - FOR(i,4) { - x[5*i] = ld32(c+4*i); - x[1+i] = ld32(k+4*i); - x[6+i] = ld32(in+4*i); - x[11+i] = ld32(k+16+4*i); - } - - FOR(i,16) y[i] = x[i]; - - FOR(i,20) { - FOR(j,4) { - FOR(m,4) t[m] = x[(5*j+4*m)%16]; - t[1] ^= L32(t[0]+t[3], 7); - t[2] ^= L32(t[1]+t[0], 9); - t[3] ^= L32(t[2]+t[1],13); - t[0] ^= L32(t[3]+t[2],18); - FOR(m,4) w[4*j+(j+m)%4] = t[m]; - } - FOR(m,16) x[m] = w[m]; - } - - if (h) { - FOR(i,16) x[i] += y[i]; - FOR(i,4) { - x[5*i] -= ld32(c+4*i); - x[6+i] -= ld32(in+4*i); - } - FOR(i,4) { - st32(out+4*i,x[5*i]); - st32(out+16+4*i,x[6+i]); - } - } else - FOR(i,16) st32(out + 4 * i,x[i] + y[i]); -} - -int crypto_core_salsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c) -{ - core(out,in,k,c,0); - return 0; -} - -int crypto_core_hsalsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c) -{ - core(out,in,k,c,1); - return 0; -} - -static const u8 sigma[16] = "expand 32-byte k"; - -int crypto_stream_salsa20_xor(u8 *c,const u8 *m,u64 b,const u8 *n,const u8 *k) -{ - u8 z[16],x[64]; - u32 u,i; - if (!b) return 0; - FOR(i,16) z[i] = 0; - FOR(i,8) z[i] = n[i]; - while (b >= 64) { - crypto_core_salsa20(x,z,k,sigma); - FOR(i,64) c[i] = (m?m[i]:0) ^ x[i]; - u = 1; - for (i = 8;i < 16;++i) { - u += (u32) z[i]; - z[i] = u; - u >>= 8; - } - b -= 64; - c += 64; - if (m) m += 64; - } - if (b) { - crypto_core_salsa20(x,z,k,sigma); - FOR(i,b) c[i] = (m?m[i]:0) ^ x[i]; - } - return 0; -} - -int crypto_stream_salsa20(u8 *c,u64 d,const u8 *n,const u8 *k) -{ - return crypto_stream_salsa20_xor(c,0,d,n,k); -} - -int crypto_stream(u8 *c,u64 d,const u8 *n,const u8 *k) -{ - u8 s[32]; - crypto_core_hsalsa20(s,n,k,sigma); - return crypto_stream_salsa20(c,d,n+16,s); -} - -int crypto_stream_xor(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k) -{ - u8 s[32]; - crypto_core_hsalsa20(s,n,k,sigma); - return crypto_stream_salsa20_xor(c,m,d,n+16,s); -} - -sv add1305(u32 *h,const u32 *c) -{ - u32 j,u = 0; - FOR(j,17) { - u += h[j] + c[j]; - h[j] = u & 255; - u >>= 8; - } -} - -static const u32 minusp[17] = { - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252 -} ; - -int crypto_onetimeauth(u8 *out,const u8 *m,u64 n,const u8 *k) -{ - u32 s,i,j,u,x[17],r[17],h[17],c[17],g[17]; - - FOR(j,17) r[j]=h[j]=0; - FOR(j,16) r[j]=k[j]; - r[3]&=15; - r[4]&=252; - r[7]&=15; - r[8]&=252; - r[11]&=15; - r[12]&=252; - r[15]&=15; - - while (n > 0) { - FOR(j,17) c[j] = 0; - for (j = 0;(j < 16) && (j < n);++j) c[j] = m[j]; - c[j] = 1; - m += j; n -= j; - add1305(h,c); - FOR(i,17) { - x[i] = 0; - FOR(j,17) x[i] += h[j] * ((j <= i) ? r[i - j] : 320 * r[i + 17 - j]); - } - FOR(i,17) h[i] = x[i]; - u = 0; - FOR(j,16) { - u += h[j]; - h[j] = u & 255; - u >>= 8; - } - u += h[16]; h[16] = u & 3; - u = 5 * (u >> 2); - FOR(j,16) { - u += h[j]; - h[j] = u & 255; - u >>= 8; - } - u += h[16]; h[16] = u; - } - - FOR(j,17) g[j] = h[j]; - add1305(h,minusp); - s = -(h[16] >> 7); - FOR(j,17) h[j] ^= s & (g[j] ^ h[j]); - - FOR(j,16) c[j] = k[j + 16]; - c[16] = 0; - add1305(h,c); - FOR(j,16) out[j] = h[j]; - return 0; -} - -int crypto_onetimeauth_verify(const u8 *h,const u8 *m,u64 n,const u8 *k) -{ - u8 x[16]; - crypto_onetimeauth(x,m,n,k); - return crypto_verify_16(h,x); -} - -int crypto_secretbox(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k) -{ - int i; - if (d < 32) return -1; - crypto_stream_xor(c,m,d,n,k); - crypto_onetimeauth(c + 16,c + 32,d - 32,c); - FOR(i,16) c[i] = 0; - return 0; -} - -int crypto_secretbox_open(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *k) -{ - int i; - u8 x[32]; - if (d < 32) return -1; - crypto_stream(x,32,n,k); - if (crypto_onetimeauth_verify(c + 16,c + 32,d - 32,x) != 0) return -1; - crypto_stream_xor(m,c,d,n,k); - FOR(i,32) m[i] = 0; - return 0; -} - -sv set25519(gf r, const gf a) -{ - int i; - FOR(i,16) r[i]=a[i]; -} - -sv car25519(gf o) -{ - int i; - i64 c; - FOR(i,16) { - o[i]+=(1LL<<16); - c=o[i]>>16; - o[(i+1)*(i<15)]+=c-1+37*(c-1)*(i==15); - o[i]-=c<<16; - } -} - -sv sel25519(gf p,gf q,int b) -{ - i64 t,i,c=~(b-1); - FOR(i,16) { - t= c&(p[i]^q[i]); - p[i]^=t; - q[i]^=t; - } -} - -sv pack25519(u8 *o,const gf n) -{ - int i,j,b; - gf m,t; - FOR(i,16) t[i]=n[i]; - car25519(t); - car25519(t); - car25519(t); - FOR(j,2) { - m[0]=t[0]-0xffed; - for(i=1;i<15;i++) { - m[i]=t[i]-0xffff-((m[i-1]>>16)&1); - m[i-1]&=0xffff; - } - m[15]=t[15]-0x7fff-((m[14]>>16)&1); - b=(m[15]>>16)&1; - m[15]&=0xffff; - sel25519(t,m,1-b); - } - FOR(i,16) { - o[2*i]=t[i]&0xff; - o[2*i+1]=t[i]>>8; - } -} - -static int neq25519(const gf a, const gf b) -{ - u8 c[32],d[32]; - pack25519(c,a); - pack25519(d,b); - return crypto_verify_32(c,d); -} - -static u8 par25519(const gf a) -{ - u8 d[32]; - pack25519(d,a); - return d[0]&1; -} - -sv unpack25519(gf o, const u8 *n) -{ - int i; - FOR(i,16) o[i]=n[2*i]+((i64)n[2*i+1]<<8); - o[15]&=0x7fff; -} - -sv A(gf o,const gf a,const gf b) -{ - int i; - FOR(i,16) o[i]=a[i]+b[i]; -} - -sv Z(gf o,const gf a,const gf b) -{ - int i; - FOR(i,16) o[i]=a[i]-b[i]; -} - -sv M(gf o,const gf a,const gf b) -{ - i64 i,j,t[31]; - FOR(i,31) t[i]=0; - FOR(i,16) FOR(j,16) t[i+j]+=a[i]*b[j]; - FOR(i,15) t[i]+=38*t[i+16]; - FOR(i,16) o[i]=t[i]; - car25519(o); - car25519(o); -} - -sv S(gf o,const gf a) -{ - M(o,a,a); -} - -sv inv25519(gf o,const gf i) -{ - gf c; - int a; - FOR(a,16) c[a]=i[a]; - for(a=253;a>=0;a--) { - S(c,c); - if(a!=2&&a!=4) M(c,c,i); - } - FOR(a,16) o[a]=c[a]; -} - -sv pow2523(gf o,const gf i) -{ - gf c; - int a; - FOR(a,16) c[a]=i[a]; - for(a=250;a>=0;a--) { - S(c,c); - if(a!=1) M(c,c,i); - } - FOR(a,16) o[a]=c[a]; -} - -int crypto_scalarmult(u8 *q,const u8 *n,const u8 *p) -{ - u8 z[32]; - i64 x[96],r,i; - gf a,b,c,d,e,f; - FOR(i,31) z[i]=n[i]; - z[31]=(n[31]&127)|64; - z[0]&=248; - unpack25519(x,p); - FOR(i,16) { - b[i]=x[i]; - d[i]=a[i]=c[i]=0; - } - a[0]=d[0]=1; - for(i=254;i>=0;--i) { - r=(z[i>>3]>>(i&7))&1; - sel25519(a,b,r); - sel25519(c,d,r); - A(e,a,c); - Z(a,a,c); - A(c,b,d); - Z(b,b,d); - S(d,e); - S(f,a); - M(a,c,a); - M(c,b,e); - A(e,a,c); - Z(a,a,c); - S(b,a); - Z(c,d,f); - M(a,c,_121665); - A(a,a,d); - M(c,c,a); - M(a,d,f); - M(d,b,x); - S(b,e); - sel25519(a,b,r); - sel25519(c,d,r); - } - FOR(i,16) { - x[i+32]=a[i]; - x[i+48]=c[i]; - x[i+64]=b[i]; - x[i+80]=d[i]; - } - inv25519(x+48,x+48); - M(x+32,x+32,x+48); - pack25519(q,x+32); - return 0; -} - -int crypto_scalarmult_base(u8 *q,const u8 *n) -{ - return crypto_scalarmult(q,n,_9); -} - -int crypto_box_beforenm(u8 *k,const u8 *y,const u8 *x) -{ - u8 s[32]; - crypto_scalarmult(s,x,y); - return crypto_core_hsalsa20(k,_0,s,sigma); -} - -int crypto_box_afternm(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k) -{ - return crypto_secretbox(c,m,d,n,k); -} - -int crypto_box_open_afternm(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *k) -{ - return crypto_secretbox_open(m,c,d,n,k); -} - -int crypto_box(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *y,const u8 *x) -{ - u8 k[32]; - crypto_box_beforenm(k,y,x); - return crypto_box_afternm(c,m,d,n,k); -} - -int crypto_box_open(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *y,const u8 *x) -{ - u8 k[32]; - crypto_box_beforenm(k,y,x); - return crypto_box_open_afternm(m,c,d,n,k); -} - -static u64 R(u64 x,int c) { return (x >> c) | (x << (64 - c)); } -static u64 Ch(u64 x,u64 y,u64 z) { return (x & y) ^ (~x & z); } -static u64 Maj(u64 x,u64 y,u64 z) { return (x & y) ^ (x & z) ^ (y & z); } -static u64 Sigma0(u64 x) { return R(x,28) ^ R(x,34) ^ R(x,39); } -static u64 Sigma1(u64 x) { return R(x,14) ^ R(x,18) ^ R(x,41); } -static u64 sigma0(u64 x) { return R(x, 1) ^ R(x, 8) ^ (x >> 7); } -static u64 sigma1(u64 x) { return R(x,19) ^ R(x,61) ^ (x >> 6); } - -static const u64 K[80] = -{ - 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, - 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, - 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, - 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, - 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, - 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, - 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, - 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, - 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, - 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, - 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, - 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, - 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, - 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, - 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, - 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, - 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, - 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, - 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, - 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL -}; - -int crypto_hashblocks(u8 *x,const u8 *m,u64 n) -{ - u64 z[8],b[8],a[8],w[16],t; - int i,j; - - FOR(i,8) z[i] = a[i] = dl64(x + 8 * i); - - while (n >= 128) { - FOR(i,16) w[i] = dl64(m + 8 * i); - - FOR(i,80) { - FOR(j,8) b[j] = a[j]; - t = a[7] + Sigma1(a[4]) + Ch(a[4],a[5],a[6]) + K[i] + w[i%16]; - b[7] = t + Sigma0(a[0]) + Maj(a[0],a[1],a[2]); - b[3] += t; - FOR(j,8) a[(j+1)%8] = b[j]; - if (i%16 == 15) - FOR(j,16) - w[j] += w[(j+9)%16] + sigma0(w[(j+1)%16]) + sigma1(w[(j+14)%16]); - } - - FOR(i,8) { a[i] += z[i]; z[i] = a[i]; } - - m += 128; - n -= 128; - } - - FOR(i,8) ts64(x+8*i,z[i]); - - return n; -} - -static const u8 iv[64] = { - 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08, - 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b, - 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b, - 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1, - 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1, - 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f, - 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b, - 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79 -} ; - -int crypto_hash(u8 *out,const u8 *m,u64 n) -{ - u8 h[64],x[256]; - u64 i,b = n; - - FOR(i,64) h[i] = iv[i]; - - crypto_hashblocks(h,m,n); - m += n; - n &= 127; - m -= n; - - FOR(i,256) x[i] = 0; - FOR(i,n) x[i] = m[i]; - x[n] = 128; - - n = 256-128*(n<112); - x[n-9] = b >> 61; - ts64(x+n-8,b<<3); - crypto_hashblocks(h,x,n); - - FOR(i,64) out[i] = h[i]; - - return 0; -} - -sv add(gf p[4],gf q[4]) -{ - gf a,b,c,d,t,e,f,g,h; - - Z(a, p[1], p[0]); - Z(t, q[1], q[0]); - M(a, a, t); - A(b, p[0], p[1]); - A(t, q[0], q[1]); - M(b, b, t); - M(c, p[3], q[3]); - M(c, c, D2); - M(d, p[2], q[2]); - A(d, d, d); - Z(e, b, a); - Z(f, d, c); - A(g, d, c); - A(h, b, a); - - M(p[0], e, f); - M(p[1], h, g); - M(p[2], g, f); - M(p[3], e, h); -} - -sv cswap(gf p[4],gf q[4],u8 b) -{ - int i; - FOR(i,4) - sel25519(p[i],q[i],b); -} - -sv pack(u8 *r,gf p[4]) -{ - gf tx, ty, zi; - inv25519(zi, p[2]); - M(tx, p[0], zi); - M(ty, p[1], zi); - pack25519(r, ty); - r[31] ^= par25519(tx) << 7; -} - -sv scalarmult(gf p[4],gf q[4],const u8 *s) -{ - int i; - set25519(p[0],gf0); - set25519(p[1],gf1); - set25519(p[2],gf1); - set25519(p[3],gf0); - for (i = 255;i >= 0;--i) { - u8 b = (s[i/8]>>(i&7))&1; - cswap(p,q,b); - add(q,p); - add(p,p); - cswap(p,q,b); - } -} - -sv scalarbase(gf p[4],const u8 *s) -{ - gf q[4]; - set25519(q[0],X); - set25519(q[1],Y); - set25519(q[2],gf1); - M(q[3],X,Y); - scalarmult(p,q,s); -} - -static const u64 L[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10}; - -sv modL(u8 *r,i64 x[64]) -{ - i64 carry,i,j; - for (i = 63;i >= 32;--i) { - carry = 0; - for (j = i - 32;j < i - 12;++j) { - x[j] += carry - 16 * x[i] * L[j - (i - 32)]; - carry = (x[j] + 128) >> 8; - x[j] -= carry << 8; - } - x[j] += carry; - x[i] = 0; - } - carry = 0; - FOR(j,32) { - x[j] += carry - (x[31] >> 4) * L[j]; - carry = x[j] >> 8; - x[j] &= 255; - } - FOR(j,32) x[j] -= carry * L[j]; - FOR(i,32) { - x[i+1] += x[i] >> 8; - r[i] = x[i] & 255; - } -} - -sv reduce(u8 *r) -{ - i64 x[64],i; - FOR(i,64) x[i] = (u64) r[i]; - FOR(i,64) r[i] = 0; - modL(r,x); -} - -int crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 n,const u8 *sk) -{ - u8 d[64],h[64],r[64]; - i64 i,j,x[64]; - gf p[4]; - - crypto_hash(d, sk, 32); - d[0] &= 248; - d[31] &= 127; - d[31] |= 64; - - *smlen = n+64; - FOR(i,n) sm[64 + i] = m[i]; - FOR(i,32) sm[32 + i] = d[32 + i]; - - crypto_hash(r, sm+32, n+32); - reduce(r); - scalarbase(p,r); - pack(sm,p); - - FOR(i,32) sm[i+32] = sk[i+32]; - crypto_hash(h,sm,n + 64); - reduce(h); - - FOR(i,64) x[i] = 0; - FOR(i,32) x[i] = (u64) r[i]; - FOR(i,32) FOR(j,32) x[i+j] += h[i] * (u64) d[j]; - modL(sm + 32,x); - - return 0; -} - -static int unpackneg(gf r[4],const u8 p[32]) -{ - gf t, chk, num, den, den2, den4, den6; - set25519(r[2],gf1); - unpack25519(r[1],p); - S(num,r[1]); - M(den,num,D); - Z(num,num,r[2]); - A(den,r[2],den); - - S(den2,den); - S(den4,den2); - M(den6,den4,den2); - M(t,den6,num); - M(t,t,den); - - pow2523(t,t); - M(t,t,num); - M(t,t,den); - M(t,t,den); - M(r[0],t,den); - - S(chk,r[0]); - M(chk,chk,den); - if (neq25519(chk, num)) M(r[0],r[0],I); - - S(chk,r[0]); - M(chk,chk,den); - if (neq25519(chk, num)) return -1; - - if (par25519(r[0]) == (p[31]>>7)) Z(r[0],gf0,r[0]); - - M(r[3],r[0],r[1]); - return 0; -} - -int crypto_sign_open(u8 *m,u64 *mlen,const u8 *sm,u64 n,const u8 *pk) -{ - int i; - u8 t[32],h[64]; - gf p[4],q[4]; - - *mlen = -1; - if (n < 64) return -1; - - if (unpackneg(q,pk)) return -1; - - FOR(i,n) m[i] = sm[i]; - FOR(i,32) m[i+32] = pk[i]; - crypto_hash(h,m,n); - reduce(h); - scalarmult(p,q,h); - - scalarbase(q,sm + 32); - add(p,q); - pack(t,p); - - n -= 64; - if (crypto_verify_32(sm, t)) { - FOR(i,n) m[i] = 0; - return -1; - } - - FOR(i,n) m[i] = sm[i + 64]; - *mlen = n; - return 0; -} diff --git a/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/tweetnacl.h b/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/tweetnacl.h deleted file mode 100644 index 9277fbf..0000000 --- a/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen/tweetnacl.h +++ /dev/null @@ -1,272 +0,0 @@ -#ifndef TWEETNACL_H -#define TWEETNACL_H -#define crypto_auth_PRIMITIVE "hmacsha512256" -#define crypto_auth crypto_auth_hmacsha512256 -#define crypto_auth_verify crypto_auth_hmacsha512256_verify -#define crypto_auth_BYTES crypto_auth_hmacsha512256_BYTES -#define crypto_auth_KEYBYTES crypto_auth_hmacsha512256_KEYBYTES -#define crypto_auth_IMPLEMENTATION crypto_auth_hmacsha512256_IMPLEMENTATION -#define crypto_auth_VERSION crypto_auth_hmacsha512256_VERSION -#define crypto_auth_hmacsha512256_tweet_BYTES 32 -#define crypto_auth_hmacsha512256_tweet_KEYBYTES 32 -extern int crypto_auth_hmacsha512256_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *); -extern int crypto_auth_hmacsha512256_tweet_verify(const unsigned char *,const unsigned char *,unsigned long long,const unsigned char *); -#define crypto_auth_hmacsha512256_tweet_VERSION "-" -#define crypto_auth_hmacsha512256 crypto_auth_hmacsha512256_tweet -#define crypto_auth_hmacsha512256_verify crypto_auth_hmacsha512256_tweet_verify -#define crypto_auth_hmacsha512256_BYTES crypto_auth_hmacsha512256_tweet_BYTES -#define crypto_auth_hmacsha512256_KEYBYTES crypto_auth_hmacsha512256_tweet_KEYBYTES -#define crypto_auth_hmacsha512256_VERSION crypto_auth_hmacsha512256_tweet_VERSION -#define crypto_auth_hmacsha512256_IMPLEMENTATION "crypto_auth/hmacsha512256/tweet" -#define crypto_box_PRIMITIVE "curve25519xsalsa20poly1305" -#define crypto_box crypto_box_curve25519xsalsa20poly1305 -#define crypto_box_open crypto_box_curve25519xsalsa20poly1305_open -#define crypto_box_keypair crypto_box_curve25519xsalsa20poly1305_keypair -#define crypto_box_beforenm crypto_box_curve25519xsalsa20poly1305_beforenm -#define crypto_box_afternm crypto_box_curve25519xsalsa20poly1305_afternm -#define crypto_box_open_afternm crypto_box_curve25519xsalsa20poly1305_open_afternm -#define crypto_box_PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES -#define crypto_box_SECRETKEYBYTES crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES -#define crypto_box_BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES -#define crypto_box_NONCEBYTES crypto_box_curve25519xsalsa20poly1305_NONCEBYTES -#define crypto_box_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_ZEROBYTES -#define crypto_box_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES -#define crypto_box_IMPLEMENTATION crypto_box_curve25519xsalsa20poly1305_IMPLEMENTATION -#define crypto_box_VERSION crypto_box_curve25519xsalsa20poly1305_VERSION -#define crypto_box_curve25519xsalsa20poly1305_tweet_PUBLICKEYBYTES 32 -#define crypto_box_curve25519xsalsa20poly1305_tweet_SECRETKEYBYTES 32 -#define crypto_box_curve25519xsalsa20poly1305_tweet_BEFORENMBYTES 32 -#define crypto_box_curve25519xsalsa20poly1305_tweet_NONCEBYTES 24 -#define crypto_box_curve25519xsalsa20poly1305_tweet_ZEROBYTES 32 -#define crypto_box_curve25519xsalsa20poly1305_tweet_BOXZEROBYTES 16 -extern int crypto_box_curve25519xsalsa20poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *,const unsigned char *); -extern int crypto_box_curve25519xsalsa20poly1305_tweet_open(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *,const unsigned char *); -extern int crypto_box_curve25519xsalsa20poly1305_tweet_keypair(unsigned char *,unsigned char *); -extern int crypto_box_curve25519xsalsa20poly1305_tweet_beforenm(unsigned char *,const unsigned char *,const unsigned char *); -extern int crypto_box_curve25519xsalsa20poly1305_tweet_afternm(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); -extern int crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); -#define crypto_box_curve25519xsalsa20poly1305_tweet_VERSION "-" -#define crypto_box_curve25519xsalsa20poly1305 crypto_box_curve25519xsalsa20poly1305_tweet -#define crypto_box_curve25519xsalsa20poly1305_open crypto_box_curve25519xsalsa20poly1305_tweet_open -#define crypto_box_curve25519xsalsa20poly1305_keypair crypto_box_curve25519xsalsa20poly1305_tweet_keypair -#define crypto_box_curve25519xsalsa20poly1305_beforenm crypto_box_curve25519xsalsa20poly1305_tweet_beforenm -#define crypto_box_curve25519xsalsa20poly1305_afternm crypto_box_curve25519xsalsa20poly1305_tweet_afternm -#define crypto_box_curve25519xsalsa20poly1305_open_afternm crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm -#define crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_tweet_PUBLICKEYBYTES -#define crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES crypto_box_curve25519xsalsa20poly1305_tweet_SECRETKEYBYTES -#define crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_tweet_BEFORENMBYTES -#define crypto_box_curve25519xsalsa20poly1305_NONCEBYTES crypto_box_curve25519xsalsa20poly1305_tweet_NONCEBYTES -#define crypto_box_curve25519xsalsa20poly1305_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_tweet_ZEROBYTES -#define crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_tweet_BOXZEROBYTES -#define crypto_box_curve25519xsalsa20poly1305_VERSION crypto_box_curve25519xsalsa20poly1305_tweet_VERSION -#define crypto_box_curve25519xsalsa20poly1305_IMPLEMENTATION "crypto_box/curve25519xsalsa20poly1305/tweet" -#define crypto_core_PRIMITIVE "salsa20" -#define crypto_core crypto_core_salsa20 -#define crypto_core_OUTPUTBYTES crypto_core_salsa20_OUTPUTBYTES -#define crypto_core_INPUTBYTES crypto_core_salsa20_INPUTBYTES -#define crypto_core_KEYBYTES crypto_core_salsa20_KEYBYTES -#define crypto_core_CONSTBYTES crypto_core_salsa20_CONSTBYTES -#define crypto_core_IMPLEMENTATION crypto_core_salsa20_IMPLEMENTATION -#define crypto_core_VERSION crypto_core_salsa20_VERSION -#define crypto_core_salsa20_tweet_OUTPUTBYTES 64 -#define crypto_core_salsa20_tweet_INPUTBYTES 16 -#define crypto_core_salsa20_tweet_KEYBYTES 32 -#define crypto_core_salsa20_tweet_CONSTBYTES 16 -extern int crypto_core_salsa20_tweet(unsigned char *,const unsigned char *,const unsigned char *,const unsigned char *); -#define crypto_core_salsa20_tweet_VERSION "-" -#define crypto_core_salsa20 crypto_core_salsa20_tweet -#define crypto_core_salsa20_OUTPUTBYTES crypto_core_salsa20_tweet_OUTPUTBYTES -#define crypto_core_salsa20_INPUTBYTES crypto_core_salsa20_tweet_INPUTBYTES -#define crypto_core_salsa20_KEYBYTES crypto_core_salsa20_tweet_KEYBYTES -#define crypto_core_salsa20_CONSTBYTES crypto_core_salsa20_tweet_CONSTBYTES -#define crypto_core_salsa20_VERSION crypto_core_salsa20_tweet_VERSION -#define crypto_core_salsa20_IMPLEMENTATION "crypto_core/salsa20/tweet" -#define crypto_core_hsalsa20_tweet_OUTPUTBYTES 32 -#define crypto_core_hsalsa20_tweet_INPUTBYTES 16 -#define crypto_core_hsalsa20_tweet_KEYBYTES 32 -#define crypto_core_hsalsa20_tweet_CONSTBYTES 16 -extern int crypto_core_hsalsa20_tweet(unsigned char *,const unsigned char *,const unsigned char *,const unsigned char *); -#define crypto_core_hsalsa20_tweet_VERSION "-" -#define crypto_core_hsalsa20 crypto_core_hsalsa20_tweet -#define crypto_core_hsalsa20_OUTPUTBYTES crypto_core_hsalsa20_tweet_OUTPUTBYTES -#define crypto_core_hsalsa20_INPUTBYTES crypto_core_hsalsa20_tweet_INPUTBYTES -#define crypto_core_hsalsa20_KEYBYTES crypto_core_hsalsa20_tweet_KEYBYTES -#define crypto_core_hsalsa20_CONSTBYTES crypto_core_hsalsa20_tweet_CONSTBYTES -#define crypto_core_hsalsa20_VERSION crypto_core_hsalsa20_tweet_VERSION -#define crypto_core_hsalsa20_IMPLEMENTATION "crypto_core/hsalsa20/tweet" -#define crypto_hashblocks_PRIMITIVE "sha512" -#define crypto_hashblocks crypto_hashblocks_sha512 -#define crypto_hashblocks_STATEBYTES crypto_hashblocks_sha512_STATEBYTES -#define crypto_hashblocks_BLOCKBYTES crypto_hashblocks_sha512_BLOCKBYTES -#define crypto_hashblocks_IMPLEMENTATION crypto_hashblocks_sha512_IMPLEMENTATION -#define crypto_hashblocks_VERSION crypto_hashblocks_sha512_VERSION -#define crypto_hashblocks_sha512_tweet_STATEBYTES 64 -#define crypto_hashblocks_sha512_tweet_BLOCKBYTES 128 -extern int crypto_hashblocks_sha512_tweet(unsigned char *,const unsigned char *,unsigned long long); -#define crypto_hashblocks_sha512_tweet_VERSION "-" -#define crypto_hashblocks_sha512 crypto_hashblocks_sha512_tweet -#define crypto_hashblocks_sha512_STATEBYTES crypto_hashblocks_sha512_tweet_STATEBYTES -#define crypto_hashblocks_sha512_BLOCKBYTES crypto_hashblocks_sha512_tweet_BLOCKBYTES -#define crypto_hashblocks_sha512_VERSION crypto_hashblocks_sha512_tweet_VERSION -#define crypto_hashblocks_sha512_IMPLEMENTATION "crypto_hashblocks/sha512/tweet" -#define crypto_hashblocks_sha256_tweet_STATEBYTES 32 -#define crypto_hashblocks_sha256_tweet_BLOCKBYTES 64 -extern int crypto_hashblocks_sha256_tweet(unsigned char *,const unsigned char *,unsigned long long); -#define crypto_hashblocks_sha256_tweet_VERSION "-" -#define crypto_hashblocks_sha256 crypto_hashblocks_sha256_tweet -#define crypto_hashblocks_sha256_STATEBYTES crypto_hashblocks_sha256_tweet_STATEBYTES -#define crypto_hashblocks_sha256_BLOCKBYTES crypto_hashblocks_sha256_tweet_BLOCKBYTES -#define crypto_hashblocks_sha256_VERSION crypto_hashblocks_sha256_tweet_VERSION -#define crypto_hashblocks_sha256_IMPLEMENTATION "crypto_hashblocks/sha256/tweet" -#define crypto_hash_PRIMITIVE "sha512" -#define crypto_hash crypto_hash_sha512 -#define crypto_hash_BYTES crypto_hash_sha512_BYTES -#define crypto_hash_IMPLEMENTATION crypto_hash_sha512_IMPLEMENTATION -#define crypto_hash_VERSION crypto_hash_sha512_VERSION -#define crypto_hash_sha512_tweet_BYTES 64 -extern int crypto_hash_sha512_tweet(unsigned char *,const unsigned char *,unsigned long long); -#define crypto_hash_sha512_tweet_VERSION "-" -#define crypto_hash_sha512 crypto_hash_sha512_tweet -#define crypto_hash_sha512_BYTES crypto_hash_sha512_tweet_BYTES -#define crypto_hash_sha512_VERSION crypto_hash_sha512_tweet_VERSION -#define crypto_hash_sha512_IMPLEMENTATION "crypto_hash/sha512/tweet" -#define crypto_hash_sha256_tweet_BYTES 32 -extern int crypto_hash_sha256_tweet(unsigned char *,const unsigned char *,unsigned long long); -#define crypto_hash_sha256_tweet_VERSION "-" -#define crypto_hash_sha256 crypto_hash_sha256_tweet -#define crypto_hash_sha256_BYTES crypto_hash_sha256_tweet_BYTES -#define crypto_hash_sha256_VERSION crypto_hash_sha256_tweet_VERSION -#define crypto_hash_sha256_IMPLEMENTATION "crypto_hash/sha256/tweet" -#define crypto_onetimeauth_PRIMITIVE "poly1305" -#define crypto_onetimeauth crypto_onetimeauth_poly1305 -#define crypto_onetimeauth_verify crypto_onetimeauth_poly1305_verify -#define crypto_onetimeauth_BYTES crypto_onetimeauth_poly1305_BYTES -#define crypto_onetimeauth_KEYBYTES crypto_onetimeauth_poly1305_KEYBYTES -#define crypto_onetimeauth_IMPLEMENTATION crypto_onetimeauth_poly1305_IMPLEMENTATION -#define crypto_onetimeauth_VERSION crypto_onetimeauth_poly1305_VERSION -#define crypto_onetimeauth_poly1305_tweet_BYTES 16 -#define crypto_onetimeauth_poly1305_tweet_KEYBYTES 32 -extern int crypto_onetimeauth_poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *); -extern int crypto_onetimeauth_poly1305_tweet_verify(const unsigned char *,const unsigned char *,unsigned long long,const unsigned char *); -#define crypto_onetimeauth_poly1305_tweet_VERSION "-" -#define crypto_onetimeauth_poly1305 crypto_onetimeauth_poly1305_tweet -#define crypto_onetimeauth_poly1305_verify crypto_onetimeauth_poly1305_tweet_verify -#define crypto_onetimeauth_poly1305_BYTES crypto_onetimeauth_poly1305_tweet_BYTES -#define crypto_onetimeauth_poly1305_KEYBYTES crypto_onetimeauth_poly1305_tweet_KEYBYTES -#define crypto_onetimeauth_poly1305_VERSION crypto_onetimeauth_poly1305_tweet_VERSION -#define crypto_onetimeauth_poly1305_IMPLEMENTATION "crypto_onetimeauth/poly1305/tweet" -#define crypto_scalarmult_PRIMITIVE "curve25519" -#define crypto_scalarmult crypto_scalarmult_curve25519 -#define crypto_scalarmult_base crypto_scalarmult_curve25519_base -#define crypto_scalarmult_BYTES crypto_scalarmult_curve25519_BYTES -#define crypto_scalarmult_SCALARBYTES crypto_scalarmult_curve25519_SCALARBYTES -#define crypto_scalarmult_IMPLEMENTATION crypto_scalarmult_curve25519_IMPLEMENTATION -#define crypto_scalarmult_VERSION crypto_scalarmult_curve25519_VERSION -#define crypto_scalarmult_curve25519_tweet_BYTES 32 -#define crypto_scalarmult_curve25519_tweet_SCALARBYTES 32 -extern int crypto_scalarmult_curve25519_tweet(unsigned char *,const unsigned char *,const unsigned char *); -extern int crypto_scalarmult_curve25519_tweet_base(unsigned char *,const unsigned char *); -#define crypto_scalarmult_curve25519_tweet_VERSION "-" -#define crypto_scalarmult_curve25519 crypto_scalarmult_curve25519_tweet -#define crypto_scalarmult_curve25519_base crypto_scalarmult_curve25519_tweet_base -#define crypto_scalarmult_curve25519_BYTES crypto_scalarmult_curve25519_tweet_BYTES -#define crypto_scalarmult_curve25519_SCALARBYTES crypto_scalarmult_curve25519_tweet_SCALARBYTES -#define crypto_scalarmult_curve25519_VERSION crypto_scalarmult_curve25519_tweet_VERSION -#define crypto_scalarmult_curve25519_IMPLEMENTATION "crypto_scalarmult/curve25519/tweet" -#define crypto_secretbox_PRIMITIVE "xsalsa20poly1305" -#define crypto_secretbox crypto_secretbox_xsalsa20poly1305 -#define crypto_secretbox_open crypto_secretbox_xsalsa20poly1305_open -#define crypto_secretbox_KEYBYTES crypto_secretbox_xsalsa20poly1305_KEYBYTES -#define crypto_secretbox_NONCEBYTES crypto_secretbox_xsalsa20poly1305_NONCEBYTES -#define crypto_secretbox_ZEROBYTES crypto_secretbox_xsalsa20poly1305_ZEROBYTES -#define crypto_secretbox_BOXZEROBYTES crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES -#define crypto_secretbox_IMPLEMENTATION crypto_secretbox_xsalsa20poly1305_IMPLEMENTATION -#define crypto_secretbox_VERSION crypto_secretbox_xsalsa20poly1305_VERSION -#define crypto_secretbox_xsalsa20poly1305_tweet_KEYBYTES 32 -#define crypto_secretbox_xsalsa20poly1305_tweet_NONCEBYTES 24 -#define crypto_secretbox_xsalsa20poly1305_tweet_ZEROBYTES 32 -#define crypto_secretbox_xsalsa20poly1305_tweet_BOXZEROBYTES 16 -extern int crypto_secretbox_xsalsa20poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); -extern int crypto_secretbox_xsalsa20poly1305_tweet_open(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); -#define crypto_secretbox_xsalsa20poly1305_tweet_VERSION "-" -#define crypto_secretbox_xsalsa20poly1305 crypto_secretbox_xsalsa20poly1305_tweet -#define crypto_secretbox_xsalsa20poly1305_open crypto_secretbox_xsalsa20poly1305_tweet_open -#define crypto_secretbox_xsalsa20poly1305_KEYBYTES crypto_secretbox_xsalsa20poly1305_tweet_KEYBYTES -#define crypto_secretbox_xsalsa20poly1305_NONCEBYTES crypto_secretbox_xsalsa20poly1305_tweet_NONCEBYTES -#define crypto_secretbox_xsalsa20poly1305_ZEROBYTES crypto_secretbox_xsalsa20poly1305_tweet_ZEROBYTES -#define crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES crypto_secretbox_xsalsa20poly1305_tweet_BOXZEROBYTES -#define crypto_secretbox_xsalsa20poly1305_VERSION crypto_secretbox_xsalsa20poly1305_tweet_VERSION -#define crypto_secretbox_xsalsa20poly1305_IMPLEMENTATION "crypto_secretbox/xsalsa20poly1305/tweet" -#define crypto_sign_PRIMITIVE "ed25519" -#define crypto_sign crypto_sign_ed25519 -#define crypto_sign_open crypto_sign_ed25519_open -#define crypto_sign_keypair crypto_sign_ed25519_keypair -#define crypto_sign_BYTES crypto_sign_ed25519_BYTES -#define crypto_sign_PUBLICKEYBYTES crypto_sign_ed25519_PUBLICKEYBYTES -#define crypto_sign_SECRETKEYBYTES crypto_sign_ed25519_SECRETKEYBYTES -#define crypto_sign_IMPLEMENTATION crypto_sign_ed25519_IMPLEMENTATION -#define crypto_sign_VERSION crypto_sign_ed25519_VERSION -#define crypto_sign_ed25519_tweet_BYTES 64 -#define crypto_sign_ed25519_tweet_PUBLICKEYBYTES 32 -#define crypto_sign_ed25519_tweet_SECRETKEYBYTES 64 -extern int crypto_sign_ed25519_tweet(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *); -extern int crypto_sign_ed25519_tweet_open(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *); -extern int crypto_sign_ed25519_tweet_keypair(unsigned char *,unsigned char *); -#define crypto_sign_ed25519_tweet_VERSION "-" -#define crypto_sign_ed25519 crypto_sign_ed25519_tweet -#define crypto_sign_ed25519_open crypto_sign_ed25519_tweet_open -#define crypto_sign_ed25519_keypair crypto_sign_ed25519_tweet_keypair -#define crypto_sign_ed25519_BYTES crypto_sign_ed25519_tweet_BYTES -#define crypto_sign_ed25519_PUBLICKEYBYTES crypto_sign_ed25519_tweet_PUBLICKEYBYTES -#define crypto_sign_ed25519_SECRETKEYBYTES crypto_sign_ed25519_tweet_SECRETKEYBYTES -#define crypto_sign_ed25519_VERSION crypto_sign_ed25519_tweet_VERSION -#define crypto_sign_ed25519_IMPLEMENTATION "crypto_sign/ed25519/tweet" -#define crypto_stream_PRIMITIVE "xsalsa20" -#define crypto_stream crypto_stream_xsalsa20 -#define crypto_stream_xor crypto_stream_xsalsa20_xor -#define crypto_stream_KEYBYTES crypto_stream_xsalsa20_KEYBYTES -#define crypto_stream_NONCEBYTES crypto_stream_xsalsa20_NONCEBYTES -#define crypto_stream_IMPLEMENTATION crypto_stream_xsalsa20_IMPLEMENTATION -#define crypto_stream_VERSION crypto_stream_xsalsa20_VERSION -#define crypto_stream_xsalsa20_tweet_KEYBYTES 32 -#define crypto_stream_xsalsa20_tweet_NONCEBYTES 24 -extern int crypto_stream_xsalsa20_tweet(unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); -extern int crypto_stream_xsalsa20_tweet_xor(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); -#define crypto_stream_xsalsa20_tweet_VERSION "-" -#define crypto_stream_xsalsa20 crypto_stream_xsalsa20_tweet -#define crypto_stream_xsalsa20_xor crypto_stream_xsalsa20_tweet_xor -#define crypto_stream_xsalsa20_KEYBYTES crypto_stream_xsalsa20_tweet_KEYBYTES -#define crypto_stream_xsalsa20_NONCEBYTES crypto_stream_xsalsa20_tweet_NONCEBYTES -#define crypto_stream_xsalsa20_VERSION crypto_stream_xsalsa20_tweet_VERSION -#define crypto_stream_xsalsa20_IMPLEMENTATION "crypto_stream/xsalsa20/tweet" -#define crypto_stream_salsa20_tweet_KEYBYTES 32 -#define crypto_stream_salsa20_tweet_NONCEBYTES 8 -extern int crypto_stream_salsa20_tweet(unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); -extern int crypto_stream_salsa20_tweet_xor(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); -#define crypto_stream_salsa20_tweet_VERSION "-" -#define crypto_stream_salsa20 crypto_stream_salsa20_tweet -#define crypto_stream_salsa20_xor crypto_stream_salsa20_tweet_xor -#define crypto_stream_salsa20_KEYBYTES crypto_stream_salsa20_tweet_KEYBYTES -#define crypto_stream_salsa20_NONCEBYTES crypto_stream_salsa20_tweet_NONCEBYTES -#define crypto_stream_salsa20_VERSION crypto_stream_salsa20_tweet_VERSION -#define crypto_stream_salsa20_IMPLEMENTATION "crypto_stream/salsa20/tweet" -#define crypto_verify_PRIMITIVE "16" -#define crypto_verify crypto_verify_16 -#define crypto_verify_BYTES crypto_verify_16_BYTES -#define crypto_verify_IMPLEMENTATION crypto_verify_16_IMPLEMENTATION -#define crypto_verify_VERSION crypto_verify_16_VERSION -#define crypto_verify_16_tweet_BYTES 16 -extern int crypto_verify_16_tweet(const unsigned char *,const unsigned char *); -#define crypto_verify_16_tweet_VERSION "-" -#define crypto_verify_16 crypto_verify_16_tweet -#define crypto_verify_16_BYTES crypto_verify_16_tweet_BYTES -#define crypto_verify_16_VERSION crypto_verify_16_tweet_VERSION -#define crypto_verify_16_IMPLEMENTATION "crypto_verify/16/tweet" -#define crypto_verify_32_tweet_BYTES 32 -extern int crypto_verify_32_tweet(const unsigned char *,const unsigned char *); -#define crypto_verify_32_tweet_VERSION "-" -#define crypto_verify_32 crypto_verify_32_tweet -#define crypto_verify_32_BYTES crypto_verify_32_tweet_BYTES -#define crypto_verify_32_VERSION crypto_verify_32_tweet_VERSION -#define crypto_verify_32_IMPLEMENTATION "crypto_verify/32/tweet" -#endif