From 07b9848f4abfc65451a3c82f08a0023e7633693f Mon Sep 17 00:00:00 2001 From: Marc Schoolderman Date: Fri, 20 Dec 2024 16:09:30 +0100 Subject: [PATCH 1/7] add new exercise with Qoi interface (backport from rust-training) --- .../ffi/exercises/qoi-bindgen/.gitignore | 1 + .../ffi/exercises/qoi-bindgen/Cargo.lock | 1009 +++++++++++++++++ .../ffi/exercises/qoi-bindgen/Cargo.toml | 8 + .../ffi/exercises/qoi-bindgen/description.md | 177 +++ .../ffi/exercises/qoi-bindgen/image.qoi | Bin 0 -> 237804 bytes .../topics/ffi/exercises/qoi-bindgen/qoi.c | 2 + .../topics/ffi/exercises/qoi-bindgen/qoi.h | 649 +++++++++++ .../ffi/exercises/qoi-bindgen/src/main.rs | 11 + .../E-rust-for-systems/topics/ffi/topic.toml | 14 +- 9 files changed, 1869 insertions(+), 2 deletions(-) create mode 100644 content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/.gitignore create mode 100644 content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/Cargo.lock create mode 100644 content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/Cargo.toml create mode 100644 content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/description.md create mode 100644 content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/image.qoi create mode 100644 content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/qoi.c create mode 100644 content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/qoi.h create mode 100644 content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/src/main.rs diff --git a/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/.gitignore b/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/.gitignore new file mode 100644 index 00000000..ea8c4bf7 --- /dev/null +++ b/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/.gitignore @@ -0,0 +1 @@ +/target diff --git a/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/Cargo.lock b/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/Cargo.lock new file mode 100644 index 00000000..796df20a --- /dev/null +++ b/content/mods/E-rust-for-systems/topics/ffi/exercises/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/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/Cargo.toml b/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/Cargo.toml new file mode 100644 index 00000000..e570fa02 --- /dev/null +++ b/content/mods/E-rust-for-systems/topics/ffi/exercises/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/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/description.md b/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/description.md new file mode 100644 index 00000000..c97f328c --- /dev/null +++ b/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/description.md @@ -0,0 +1,177 @@ +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. + +However, the generated code will likely be 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). + +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, which can be installed with `cargo install bindgen-cli` + +Steps: + +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("qoi.c").compile("qoi"); // outputs `qoi.a` + } + ``` + + And add this section to your `Cargo.toml` + + ```toml + [build-dependencies] + cc = "1" + ``` +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. + +### Inspecting our bindings + +In the generated `bindings.rs` file we find this signature for the `qoi_read` C function from QOI: + +```rust +extern "C" { + 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: + +- 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 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 +fn read_qoi_image(filename: &Path) -> ImageBuffer, &[u8]> { + todo!() +} +``` + +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 +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! + +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 +#[cfg(test)] +mod tests { + use crate::read_qoi_image; + use std::path::Path; + + #[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)); + + assert_eq!(image.width(), my_image.width()); + assert_eq!(image.height(), my_image.height()); + + assert!(image.pixels().eq(my_image.pixels())); + } +} +``` +If you add this test to `main.rs` and run it with `cargo test` we should see: +``` +running 1 test +test tests::test_qoi_read ... ok +``` + +### 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. + +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]>; + + fn deref(&self) -> &Self::Target { + &self.0 + } + } + ``` +- Now update the `read_qoi_image` function to return an instance of `MyImage`. + +### 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. + +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. + +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 +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 +``` + +(The LLVM IR can be generated using `cargo rustc --bin qoi-bindgen --release -- --emit=llvm-ir`) + +The solution is to use `std::mem::MaybeUninit`: + +```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/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/image.qoi b/content/mods/E-rust-for-systems/topics/ffi/exercises/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 zQf=LZRqbi&+6;DlQHzq0+DE}Llm^V5NV7LDr?T^BISIC7hqh+p3|hChkRskP=8i;q z+ENgzTXhKrzsFFJZN3d+EfU={?%h=*=8UqaXKrL}X zE3GQZRXGAwu*Seps4ad&??ect5`@b}mf05m6r!b4pr;_O>H{tI+}0&@^V_@H8&pS$fBgkf2d^lK9T3l;oKwwoYtM+ikjtb+DhzX z=X7Vm<$W~XgUN=9wAqL;)HOox&e6E;@;SDS)OljM@zu!BWcS+%^zpGhhNG11#07P{704QRQaM8ogPV zzIJdXcdt1{&t<1V|5Q?Il@rf)cuB08-e4%2iXCEhgcL@mTJR^M(x^w6@&2Emf6-na z!u>U|-)&s5!o)TY=S9J*NmMLRQ5jLS(4%^O1R|rDBBMC+`UgkaM$^+LW^8}%5_b2& zl5M|sScE30+0gxPg;v)V&?~ODyLCo3lN$?=q{0Cd+PYe3&&Q=lehRmZ11OROnu2^EXwMLbu+Yxj#lj9%@M!~9 zTHHGTlrUU?!Us*MnW126L))7oRR09Q8jE*vJ z@hOR#-@r)~c&O;bE$~AZf8CCYC^K^xF?be9Rn}4Ez!%`ffFRkcf$4+pNO)=HCh1yvu@^G+KY zLjDhNDN2ZF+`&W^AXbyKLQBbO-W9#`p-9sD(s)LH3;fdfd6Q}Nu3W0Qeo2_Cax~Ba zuusIo=1$h zd)YA&Bg&Y(y?LKXwg6~&C!ocSK#Fw`Jc$c0m>>gGP7#u@DN_kkrXWy(wsC?Xpi#qU zeZg)deCu$$F4y?dvsTAG7`n!?%JgJiWdm--!^}~c63+M?lz>N6LX^WE<@9M?LWA{6 zg5n*Vj(L{I9F!EAd$GDjIjm8q&1E#&Gn+gQ&S=YV5F^l2CNw82PW-)%v>QrxP1j8}&;Ro6Ut}D^&uIqI-sq>^)C@_L27JDd4H;i6O z98D7kzfgpKk^Ti70t)^ctj0NT>aZ}i9Hv$q)M_Xm0zP#K@WT(3jj?4I`6ZwHK-*U! zm4oW;AK;nPr|-_O=P0W2 z*9`Qv?1{aPEr%;cJz00whn&MQFk{fbK?w(A*mIF_b{$>*>4wPnl+)usP?>elqC}^~74EHv z@a*PP+J)3Q$K(jkL|+R!87=;Hf3%<>K`Lw%Jw10aJ^b-|ZTS$ogyXQ^TEB!M(v5lr zYA2|WO%;&J5J8zfxJpXO zsZx6Ys7s{^V@TD=wiac7>C3z;V<>0S9-g}W0zLtO0)A*MzODjnfP-JQ9%}WonVrD?7aq)S51S*PYW+fF=Y%)kO!d? zZ;+fYXwX3OK#Z#ZpguYUp4A}LC5d7L{v~gw|>1(FS*}h z6f48)L9Fb!vOT?UN6FogeSio+4euhZ4Lx3v{$>pfnI zcF1>U;6$?5hAXgfjF52se5Q`g9a}ONs~9eaUZ>N;rr}o>zmTJKb>EJm)=|&;{0j$l zi+qmuPM$`$UVWJ!y)?p_Zi|lYS{O;*i8xRdx(GMK)kLRdCN<^~!GXs>C?YE(o>E9(uYgq@ zdU0lSpp+mRpsRxh;V5-{5t@o4)un`J8Or*CC!N+`+Cle!d(2sqj5BoMr|a~*J3UG< zM@0fxL8E7e)7ND#dOi!i=)etKpCV;#LTw5}Y2sv;MEz%(I9k)5QLi3EYxfjT)Z0ny zjzFjI%w`QR`5ZuK7qTNzE?r%nWY?V;LqR%LD}{9ZM$!r61bQ@TSW!~CGkx=2y8OC{ zEYBN)91YsErP}bSeqJ$P5o09KZygMPP?hGem-vx_YTw_(UuPRyQP zcYXj30UkIvfx$>f!b2XEU;`vh+`*;a2?r9&bB4odXbVii!3IIkaPeQ` z2lG4Mu3S!)-<>DUf>lxV50`1A#}*Y88-+QR8Ev$60OKfp_C$L!&XM7eiF>->UdX~L z$1<~?=(padGndb6tC0KPNNn25cd6&haaeyi65zDD`~7s~DY`PV&J&?K9TB0^=puA7 zb)GUBXQ?t2GIj0q932CjJsLH<`1z8qbaC=z8aZSPnrfKUa9WSrWn$fchQL}?z+i=` z%fiqIvw-$3KH1KRqkZNSET{gPCtVa@0#+qP{wgkpfd5X#S_Mw@=|}JS<;EsT9Fd^C zzGR~40=o&@vmCbP;(&VDx0tYU36d=VD>*2^Pb@j>fHbht_?+hTP9HrOCJ7(l34Z`! z5(e^u^J`^L0=--^i}v0;CK^Ah>GXH!Xt-zQz=SAhiZsYPFe*AqiH?E_+=C}kIecLY znz(E(`v|DGaR|yQEzAg9YZPIlv7Nr;T&1>p!+6?yY(MpX+oY>|5TSEN@Y0G)(&!}I zXmk$o67TD<^bxQ%e5ddWDS|q^I;#F;1DP_CrqR98FXq*jZu*^0Or1vEo*EVu1O!k9 zfL&2+8nvQf9q?$>B^u~MnA%0pAy=|%^;hf{v_oNf*Qdv5WNw!Mi95c^Tn(>#FM$lh0>xqD1C$bw zX5fWCi$KY?ZV~l(^EIq89ImrP7s!Kku7M%jeewutXO7dIx9hyTl43ov#1R%=NxY8G zDfLfy2^p_ncUgRqS6&utj&I5QZAlXWn}WCaBi!OGw=M!E1~(f1Jo`AciGEJ#M|d=b zOir0Xk6s*6G@;Z=w_#Q$K5t|*BJhDzu6EeeYK^)^qps9w0F6d13A~WV%-^t&Ypm^@ z$QG{1%~t=SQ9lgJyA&B))0-|_xefqoFsYeK=GU12*O-RaT^SJWcg~EZ_j3*uR=Lf< zXM?<0Y)+5^13!7tK>jrdsNh=z{Yq$zcQ$?hCpIWhIZJoR%mfAB00gpMf|3~u2N^AB z9~OMdtE;%)>8cJNmvDkST9};td6*JDfMfEm>w&F6~fy>a3h>z&G7P^5b7G= z8kXsF8nJS|ukoKG0L*98dROej)!zdRgvv%AaaxYSHfrISsL{D^I zi?{;OZ2Z8$u^k2W;z&WEl_SQ`gBOP_T-D3%of_69GwsP-5ZFXd=4s0^{~H7P||tH*U&w{H%#M-}JH5 z99O^84$7ODObQLLanKx#M~6xv+lTvxm*TXR{fRxb*`6N1j<0{3? zp3G|{^}tzDp!ptn#*?~751TroM?_c{>1^YLUr-HM-FEB%^-oXYKTtZC9!jV~@tZ*JyZ119PcsP!x%BuN2LR0w++x*xjvxBy=uCeF0EL&)&u&9wi zO6KQjc5t0Q9iFMV4;UQtM zzzAUyYrO-@S&o;NSQ<-&gi1XcR?tOjMo*yoFAUq73Z*~&E{<^6GU>8a^MK4bS@gyG zC-aY?P_tvx5gL{|LsMzhJWSU}SxH)rMyt~}wHh5xRnbD>wW1`HxjeV51|AikGsRKG zM^<|K{k5^@hAdk^JqM3otqyYi-|oW)x9(n&Rd=C&jm7f1{9K|lK=vDhDU{=z2URsJ zallo3U_fBuL)v_GcYWmWKkXU1{o8$dxoj2<@uu13)*-D!oUKFTET1BuUpJDB3ujTc z8DoM~r(tL^bJx*^FSaRG5b@)me$bvVtkKenZQ0b%Hi0G5k%9H^!4X)GFb7-~tTw+P z1RCqk!p(28l&ixe7I1Zh+6FO}zyV+)dXwZ9qe-VKe}SRwHYH41OH_bXu5Cyn2GtG9mm;;RPlW&cP1mYQq{3 z>T?qobqVqoZ2ZD`aPfAaQ!CIZ9)5*QQ$4R%3rym_N(ne?4^XlKK%jxPfPju<(cnxII87d$Lco;H%8|1^< z0ZbzBC#)Ozx(vMmMru}<2uUsDZHu^vx@e##k|xXs9Mr%AEX=?#HeK+cz=tu8kW>vY zc}O?tMLIWS68mEbrRnso;T5uONoA}mteQuF9f;7{;sPHNd2rZTM!_1LMuvZ4!?RA~ z(8@lrWNj%>$^c9fj#AXhIz|z2DR@WQ4|h8`PMN!Qwe?KzXDgn+Z~Te-yN(tvy#ZAmm61l>%wt;FT49J^um|(b<`8d7 zsR>y0B-uXshTa{p!L!c6Abgq&lhYg-E@!K z@64d5v!^n!HCD|X<~|0|Mz7|+O0_@M_tkvn*ug=!|)*W(5r`O|!Od zuWpYZP_1!Tpv@1^o}7oHATPX6!_Ups70$@C70$D<(<;0#1olPdB6G2!IHmq!*!s?P z7Y$9BN}m+v)1@0XzP_iuHjK9H-^tP;n=CC`wvueET0%;iM1&k?N@?({NvaEwjxbpz zg((n_40s$Y5CD#CreFkM4*WsRcn@;od!Ok*64KBE3<81Shai!3mM=m2kOT;lU~B%E z{|n3;c!#+o49^f3)!*FYQtJ8CFjA&WrAIKEgG;8XT;N(owNBYuVD?vL&8dHHuI5aLPHbi@K$bF{`d+f?*&(VR&#t96wTqARA_qFh#8j zbK*{6b^&`ph*&=OVmgu7?DN}_+JWEVeV7wAJ&+JKJ^URArTB9eBNcUcsUff`r-UJ6 zsPy$o^bivBygTP8-JCFv>|+HuLxFI9r0-dnfATNzyI=;g%2$POR71`)r$6ord#xvPS@5(#$ zN>U%I{&bVbY}xvSZ|cK!I*a2%ZAb)^HFyPWg3f2|+N&q%4QTeJL3t*_Cr;bER}r8Ct?HVBIx0$PF8sL{;4`_@;Y zd#+4PJ8vDKp=DNgChTQzhZYS8j)#pxlYIFD8gap9`^e&a*7QQnsMG18|mj?f7M>ylu9pWyh&YCUX{%8GR9{#lgRj?&n%%4CHK%?>H!x8 zBa_i`p?b*NgCA99m_rp-0wDku2_pr#;h;cbARazJX<#Gajj-^r$guPj;?^wY1c$Fc$Hr;*bw@FBnt%o;Ev z8evmdUhpH;zuAu&M5isqhQOlrU()`pQ&}bO6_*$1(7@~|LRLI19r#XG1IZ}*epoBLySE+Lx&vZ#n#so!5@KZWf#V^!mNH<4@Vhnp zDh*PE5)f06oXUo&%|EPHN=SN$Iz)j0g@izegapa_jI{>Ae0l}VD)2>5vzemj%HK@t zZ8B@Ly|uj^Hf+87yC_|OC|$B;*~CC~yC}*HC)<#R+s0 zrKRh}adh{^=QG2$MogEx@hXX4>sdaWKeTKq`b1{rbE zxSe+T(0iD&s$GS<>~dZzC}=y2Q5j^1Hxo5Rj^}o5Ba9i_vEe$la;?kV!CSdXHZ5DU zfI9UZ8FamH!xyeE7vnJ8azR57q2l3oBMT1rC&U^O06&IB1Awq21_imda&==)mAuyRi_# z?yx9jLS$go@FJ{K9ahT%1816z5j#hJXPs)4lt)C5py?yVQTp@a3L{p%LcNjfcc77P zI1f4ViHXFXDN}_9Pz$dFjx9@wPFux33Cjw90B;0EfK6YqeJWg1Vx+yRj?)`O^99YY zRnqoz*kF$!B>h-26iAI$8?CQI5B9v1MYQOwqcFZ;ha)L_8%@};0K3ejI0X&vjTQ>y z$#31c|J9)z;-FSO*UFVMf7vqXG3b>w>Y!UiJH9-$fAQ8O$o_EAa)>*vD1}9$wG@Kb z2BxMX|CY!2i|kEFn9sL?Ou!D=+J}Tt%$|le0^uDWOJTu~AqxDghB$~MC-RgU^rY^- z{T2OD_a~AN+(R(7;vIUn+^X1I*32Y1f7esOEuMCLA&tC}j-3$y_d0A-uc0=U2*|~Z z!X-rpzJp{ixA@+}9ef~235}YWN{@fU#1?cG+@NU71nM&FRk^>-ok{yn!aSnYwiaP> z?t$GDnP$xHrP!`RDop68P+hdbOXd(N(+XA*R!SHp53>q8G{UJV7q$!TNxcmMh1?RT zW4IclZu98uK$VjQ{n*FAt?)_R{ov9Hw8eY%cdYufVB2cixA0^;FNiUJ<31XaXYOZ1 zkgL@@bo#O+Zi|JfD4{pLSWF+3AK%$J!|uvWrT63=6rDTy40fk90?oN2cp&f&Z>&xe z=?RAcd%8G1(K_gEV=l9#0q55CdX-n$2Mv+OHaQ_-16l3c14UP3~BCZrQ@)D>C} zY}29q8clmm3FdKpdG{2j?h1BQqOZ(SvzVSeZH21q`%3A3ZBm?U%imcK?u~`LX-H`r zsVBY2*oJ2o8R5a!V=1r=ESxvkhd9GJ1HNt1cKZC755UWt=F{_YQ>jbxt5Saxrjpt) zS7`oj1=LV?etn2^*74L8L9@fwN(wG91v`R*9ZA7X#yQx*wggt?c9!a_4Xub! zePK(O2E+~29-b}UN0R`&+AulzZ)krjnso)**^>}*xcZscV}Pe9oPvJ3OaVEb5Qs9& z%=N7Dx_&b5C7(Xi(A*ic^^=2iAX6$dd*PFQQd~>}bEfEJtzI$lhJ?#DJ&oA<7G*ki z)5020!7_VE?m2|JbK_29ITLdqN9C5)lI$)QaQpUrh)K(6SQTzV+uqLwJrFtB&*3$= z8!#_QahO8D_g))kuPOAo;oS5ibUIN<1=P&vP+V5)soWP73*nCf@hJjvp{(Xi zKno47cNiKK9B+zGGSl(D%J|OPVv6i#n6z2zmQk0fqthL>zIFx2L}ZD5n-^ng_lcwR zfWMkylA5)0Vs3n^U??_F2HvU)tLmmrRS9fm1T6@I8F42+**PADYZ?5vXya}piAQHo z?w2H6g-I7#2jmtSAry$ZVZi|?>p0`8>t_=#AXJxTp_6$3`=_$nd5hYTrSN@WvQ4ba zr7+wwTWl`6meslBGuj)a~KE+35nL!W$r-8WQMu(O&@;r6+TnMpXsHf}&hoXxJ-o@fcD zupa5jm6_Bz*{9c$(L!~z8lhz!XU;}Qnv#x~wQ#NtA5xzQuTk~oOWMn*IDCDSx+TBb zIo$$Zv#*`{rA;7jO_dnk^rhnj>1`8PubY`$%Jx=>R$Dm`u*x>CDY(YQU<2)7)qT6F zI$d>IgdH5Q3hV9&YXljbeP3uXrqfaX>`96hIR@aV)!Ct{?AbGULw{}ToB>sQtOw4x zg$2e#cxZ}NFYBPAIa~IkI(({~x4wFxpQhI*>1zS9f`%J3l2X#{cPYbjfId7|f{lsg zxrgZ09djr;Z*rWRSe}O?Z#XeoyZ;dV@yDOrmfQ%X)tidn*TFt(VqRYRRM3wNY2_zT zVr(?fHaPI`wt%xxSfR9yU^@%vg1({6Y9~Hc+N&FNSz(+%61uEGNw<4JzMdnB~G#>+GX1lPqdV5^+5Nc=if>Z+#MOsc`Jc);k-=P zXSUIEyV?fxO=ge68Bg=aOX%P?Un4mEpZzj2n$s3%2#}?8seAA4y-Alko_2q8MEGoo z3XXXc>XkY!XONs8-!k5Yqy%RrklAY0Qfh^XZmn811N2!BZJuD&f2^vD4Y~_hA0kq& zcfhhIS+!a0aWmxtJQ&n|7EbseryoC)Wcakj$P=n`dMF%uJ^RYgdV35LecqS8O{@>9m-@ z!>?MT^v<18G=F8mnC50 zU{QP|3XYZP)lLKM)tsi7y*~T7bzDcbokepsn#`UW*{0QiPEXrc?=i!X#h*}mtrl&{GF$_DO) zwqXV}T^wFQ`qc7>Bw?*q|RNkAk3%f$NJJVY{kWzC$V4H|O z(YUMhd~rHuu+wwaRWu=gXGPxlygM}OR1v+neRiVUCQ;68*(Rw)%NA|gv}{ukTI_i- zdRth^n`mLbOnskzHRyNJ#lJ$1lG97=G$wh@n)v@x%=ly)>PagyTG+>drr~mPl+tJj zp>S^_ZKB`{aBPvQ*OaiXQRuV7eZ=Wa(`b52n%*X7Z$;ZXU7IQE`}UL8A73M+Je38 z)}pOnG_S3Q_A}8q)Mj{*K?xR0#)0f84{B0{~--oAi zE_;!}PTjIF?iR)k7Jfz34z8ial^7aV?J3+*Vahp7?>RrGq+J<_Ql>evr75wcY;Ds5 zfXF^XR^*nRZ!l;#1E^rz9tw$gHt5&FBa~CPBfyH0sO!;2glW&~NBub%WskHXv)aPi z#0sSmG>Fy~CcEy~cQmXXlvIt=qVe|BAg@VrUm*wKP3vvaGU>_MOg#Gb?%mgEMaTiI zLTBa==Rt#i74FQayM&}#%oroDJ~Stb6XpY-wrzEj>oiUhC^hhTaObOO(ns@s38^#I zC*q&5!Thw8EzLMF&gt@R+FJ+?lCAS7FnmbR&%uHIeCVCcg&@I3FtP(@Q(R+PA zQn?yiJEozlGZmIbBlSiWOoN5z#b+XO*|79|d-wIE_w5^J!I(B%?J|UfC+W`b4}J7j zcj4m+G{}d+;AaZwc7Wlr7S4Sdg7*2*BO)}f^W@B5rKLSzAEDP5&8I#VR3=J!5VrC} zycfHmZSimgxJm(Y!tQ|26%ci=R>7@glt&${g1-e@Ihe4pMZ)J22CHPD6-~$lIg0O4 za@IPU`TiOv_`14BaFXFUti(v8oXG;3pKP35V>1#*uN2zo^L5{dE=@P8GFF`4fY`e_ zG0vIDrSI#)tv(%tQ4we zN2bHjgOfxiciw8By{~f)LC4{#au3b^bQukL^L6SreT<>MDYG1>X2ry_iloQOEiJI_ z%~}B%;g9Oz}zz`4m@y+4P-F15wzrY)b%L>W0b_Xri@Zs8^i##l}VY}k;> z$x-|`XinjB`aJ8Kg5$2Cn1{KG2IL{YLej(r?>i31!Q%;+hoaG`eZUJ0-A~kW;3!gD-i}(= zh6Qv|@sN4;LO$xc?R&;%9UucXTO87; z6RR_*@Ya5+{t3I)*iERbZqTElBL~|u+ji*!yKkcr=IOrE>lKWQJAI)BC#-L!=Vni* z@RZkbM=B;9N*kk?V#@y?S>FL4MZJBGAtaD2fh2?kLLj7UNQD%VY}z8dOAC?(DGJCk z@E!G8U{+`C6dO`QCn2HOJ1SUaW?LE^6-A$&BBIa!O77=>?rcE){U1Rh`Y@R@_ug~Q zJ>UBkZBj@Cs)+_>-AO|WrFG(|Undhc6FM&{iWc4@&fm9979o%_%E0xzT+-23Ao+zUx)`JK$MC=|M3NV8Vz4#Yjoj=m>HDrXw zXI`enywO`Cf24kc$I$-gU$t2SGqh$dz=yh2 z4%F~NXI6l+gf zw`(cyBc3L3yNX|E&d!B&3|r7HO&z!WKXof*-C3}l&Mlcq%8sRF$NSR$4R4yWRAU_7 z|IB(wdmKVQ$Bd*_g-IH%cxMNXOzT!EZKHO7L(30uqfz@rlrzeU42UQS2);H>H+>q& zgCEoDM+~zFe2ud-yBnURKDnbTS3(Oh6#AdFB_1l~&c+vL{2Y1H_V$V< zNKl(xfWnVRLQHY*!%P~2R1fq(Y~bkuhlcL%@o8{48gVuEVbPL(;vBkT=b`;c^|z9| z^)>2WGyy36h`3^wZ5AeUH7qLxVZvXbA>prnng=!Uqr2d!7(c2iu#mpFc@~DXqU<;= zYkY`aVxP_Znhue1!>&fWo!Cfd;-%QVA$DH~u5b*ohamD+XpQs$AUoKyd&zDe-KjOu zw1an1;huStj-6P#GqyFscMY&tUN^^h-*mu*SlS$U`QWdG`PQSu9+qg+&V4j$*0L@? z1nU(VR6`lqEI{25J^V8>z*XwBi4B)2qYz?Jh+PZu35{;~-~kk>pO{YnHFyA$DrAu= zFL%=(+*c2^!rHE_AA=@TVr?)bNlr=0^df!~fRqQQ)HC7?lV@}`obI?t0h3M|eqpq@ zX88nTf^3H#m4QM8eH~1579ZWV{s7&!SKqs8&?XNJD4qmF{`FU?AXv)tmYt%pyBE^Q z6*yurZbTJkSzj!ggl=4(q8IObckgO!@oL=mI*qAcYCrCBLN15`1i~I} zw}&HSR$hJnfl<5m(SuE|(1Zj3VA3EEFD86gFvzoHK;@!FQ5J<0RRfuy{#t_sxEq#D0Gd79@1gG|j;dE$cLb>Ifu&Sg zx3CPOcQai;8eZsq#_-yswRo?=VcQh}R zjGSq?Kto5Ew83UQ4WR)|DlNYAL8_X*q|0|55hD%MV0J`eV}5;9fFE#s(j&j<7|cx4G4jPgXDR`dq9Eh zaXS2J9-HQ)iSuN-qyD`?`i?iLXxvS}hd+9{!-& zsM-B2X!jwS`|=|+v~E5weu!;LXi^dr5)+b>9m&bNJ`Hk#Paw*D@%4G@`FQ&9>^YjV z=nm=uQSR&d{WRZsSGk!|K43cVE{L1MxpGZX^+mGPETrq3q=p$fG;wbS1<+AlGSTv! z03wAx3Hb|nz^COEen&WR*osfq1qa~mXDY%dcG#FSsG^INXy`bpqVWO+jvu$S8=G#V z#j90LUV#(|&p#7?rlI6%`S{2edHKbyj$*HX$p!+A9#ZZLL1PL`Ldp#xamn$R84X|{ zuX#~x01~)30tdAQQG;R=-lO$enE^b-BWKb**pPZ#gHgXlpF$vVfasTC=sW?cy=$Ic zUG@<@wpHS&sXDsj5WQNvg7s>XfpxPhc3(F;Rqy);4cl`okm-g%0W_R5Jnkr`JvT9eJ}COBSB z$WEqaCOt!}grNSR;^B+M*rHij!f`@x))`!9`D^fwVzVcjGIKzh3T};Z!{nNF9OMhQ zQEH3_!l-=tTt*A`6nGrCcudFa8vhwzK4^hS42r!{aiAOmXs~ZZedYEQfO%vEtPO%F z2NF6ajwSvaxsF8z{DoywjxW@s4x$i&2n#Z9KP`W37s>Tn!zyFfO1kIi2B7xqp9yc* zymR#86HWxx=sM*n_?t4n12V76-p%fZFrbHo$SihxaCH_MQN&PGI4+#P=b^Y%3___( z-$&|6@19@jo+I0-eD7jZoo0j(uEudB>r%1|q}WIOnC;xb{dDQOE7ps{aQ5wET5|in zl#nxOYv0c*=$2(G=r|fy-XHww^?wz5z70Y(Qb9(;N2@r678S3yp%m(sm8kx}MaNqt z!WkMJX6kn@2h5|++^Sy3AtXep5K44!M36)imO5d0`5mzIqSuUf$$HE5oh9ICQWBJD zk=ZN)`G&~Ti%*sp%jL&`K$DEx0tm`kM=(_cj-PNN!Ux8NfI<0ZOd@)eUw!7c{NsKS z4e!^#?YW-r+xs@Mt zzl3X!@KBD5aDMps85-pekBSYCj4zs52ZGEGC3>fbr~UT*>eTuIDo9YCR4pU*m3)0mg3}111k=tWgflGlu4QGA6iApH1!^e}kvR+o(fpMw>9;@r04PtC(3F)TE)FwUkCbGjNT6P3RhLsx zQ*?lVh7v#hQn6nkJ$+y{mC!l0a4-DhW>AE8a&b>-esE1eJoq?Ob%X@OpeOdAc6jPH z`?f2zeDyX!@cT6gP{jSgUeMmniF!^))Y%*!AKo#ShVQwV;{st3#f99C2hXJ<+#97s zImWe~42le@>j{tbi&)&g9Gei}SO6Re$vSFyQnI`_DOpcX&(S;b&}UpQx>~=_g6NOS z1)qC`rp;Yuf)SN5+;Vj9{t%iuAEfTNm+1pkdtUT>u|t$u#G=f!TStBVCpKsxg#j5; z$~z`=R}T@!1VvrUwH?Jh#E;?;9zfZUEuL64FA^#7@g9JGU5YBMG52<#Md#iw_ z;UhZqzPVu^_|W?>tEJyEZD%RgmBz&-h$Jb=nUeE}xiXpONqhYEhdPn7#>_>6HZgM_9v&J56s-B@#8#Jh(~gm|?fCoR8V z*$c#%f9O>I^b$B{QRs1E%D?6|L`xLH1Z)!cM1_Z-JK-QDCpGAE1xV{nPqG{EpT4&v|qeJ^I9Enml{yqt9+E-%_!&X4jI@ ziPpLUjc*h_clz+%DfHHn_oH}j74N=06NUeIET5h{@AmcO|NIji5TnezlZY53cotfe zvO>dM782s%cZyS2xW$kx7Pm!9v?OXY?aWEBnd`_2p-pn{5y$xCk>8AQ+wzvX87 z>il_tvNnv0mN+PB-VLx!C~t;)%exb^ObgSzt{*Fr}?JF*+*PrD1S ztk|`TE=?H+SXR-F9d{y!nGD|^4lU9yLQ%O9Ie-M8=;D|f>lH_nHPj3Pw=jTG$pC~u zL{3h=x$K{XuupcbShbdt3de7lNGtANYsSM*yH-ruymGbl^onh(cWjxTdEMSM2UghM z+?3J9`qTCmq(1xvHR44mYX z0f1ki^HF%Xke{bJO%zy!DgLPZxT`!M;lGFc1wjm53Cf9KmJ~4H@ zZ`j-f-gMiR7byYCQhWQ=C%=1M3luB2-9slHT82OvQ`KsvuNF+BdAL3b+J}bW7N#k9 z(9K9up-~>e5diuW8tZf7sT;T>6m5Azq6VJSoQ@UAIq9w(ukZww65HA9pIk$kmDAVe z>{@9tB}d(7-eb}Jdo^j^CQ2GIX0xT^Sm!5K-}ir;?}v?RRkNoh&$Ov9Oy84wCe1?qMNexhC&#m&%+3r(R*lQ4)3(b0&YkV8M_HiK!D zIUc+Av@=R3;nh79eAS!r$?zGAgRlC(O|qIB%t2+Mi5u*0ph$GrE{VRKHMy!4s>go3 za(L*d4P2i2vExajR`dIgA|Y$xv1d`I1E>j!iQtYIXzr4dy-CR;UDDEXQ1}#46c+3z zK4d3c$+(;D?~mo?(@__=duab{{Ytu_W(jVfseK9O{r0cwa`w-M?j4%vm$f{!)s&3m_n3#+Ws!Km!MbBS&i@aCb=!0KAr7Qpa7r4`Z zU3F{r9Be-kOg&&ws)U~oRZ@Y8Xt-#06u+Zp|2}G1^|~=nlsvuaaVyPI@1z0qru6iw z32{aOLLdQAfD)mlB^gLZW_yluo(XfEkq>dp$1P%>`Y{H?Ua7o^6Hx?679JAhNPK`t zEe-}jGl_>cl7No2zhxAy-1-vU|NnGk9<+5JtZ1&A>(0_MPfNVdr_ol`RQo$M;{bB` zo&|ftFy3_l14aNbphanjf$-Rm@vu$F1NB)b9$=y80FQK?%YjGuii)l!o)5a;uTbxt z(H1ZI>@7R?vLIq@|794rc$pUCsw3v3juhjSz}tg07n$BrDn%ub2r-*CQ?2xwU^GWt z+=d8<^gRbbqGx<~H!b@3A$sWZZM5(F>*N6>Cw@Ll=l}g(KWlrN*+JOBorDWb1ZNjYx0=S^>D-V(nK#ea89!1odU{pF zP0xgcI4vO#e^pyk49Tq9X6NpO>d0k6%hyCP3I!gJ#Epl-Jv(Z+2dETxAoBLV==Pm& zALy&LZpZzT^KSbaA}+gEvAgZf^ctok7pIKbdAZ8JBS0+=IiXEC5g_xUoESv`4+jr= znK{M&6Uq&!t1iG?jf`X?CplSYIl4d*$k)>Iy=uPbh>O!ZS3DZ50_9l!omn~&LZNwc z0#txAAAW4M+&;Fvyz=PY)gPF_F}y|ETkR>!D=S0N_dCIhTr3naoeqID%wrF45zX$J z#6)LwVq$cn@Zm?6vga9WkEl7T(5JtCX+1G+WZQzp=hxaOf6{cAn?}3SgbTF*oiA!K zih*#!z&%k~O0U2BE`53a{A+=%PwH1&PdwC{hA&${nG0s@3>&3E3lfqM8W{;sH=;xr z2?zk7(TvnZCSb27NbW>>ZL`;-qgJlj#M7 z&&WNu02$Dwpg|=_n?4aBv#tchi^*oq$VEY*fmlW(ZTF17@sTA#fB z$rY4YG5xVbtTm~ghdZ9G{P^s$;MwuxhSI z?j*K-O0zcs9)}Z$3!rkjgeIir@UE`vi6VL3Eb3(+;}9TRg0r5~L*hy_ z$Xy~J=M>DE`O1X@tA~m*VF!|~D1jFiJXjOjz5{gX+{f1A*zoSIT~GbyOvZ1bm5B@u zjnqVB&j9F|8FdNp)5Ik;3n>Z2nG+&#SD;)fP+_25GD*{lkIBU?0%K}Ft7YYFA?3x? zdwg)r+(IRzZ=`z~-mS}3kM6pWZn^srMBjhS@`O!I3^+H8kbX54PfX*R#>r8?glg9> zq@(vOq_1wNrt>#V-xZ**Z<$GFltuLH`ek(M?pv9Ud0AM&qYjTf#@)Qm9ZVbR!c5M5 zax!Al33`x^s8oP^N?(ySgl z^agK#I2o*12+Bp~h@Wc|eAgyT;3*1-Ju4|*C@C7K7`hdItZ=%b6Me7%Ca3!Z5YLrt zPTKZO@Dk1A-Rafu-=p#8Zr?K#h-hwY`(fM{j{}L>*Ka?fK|W3wSz>UBBs3N0R1vQt z4|$Y-m6L^u52L3Vb~ET6)uG#UA!(tJp>jaP0due`Gu!&W%hLp;ofdACc*x^rn!-g8 zLMc=8a{?VxhdZHoP@ie7bj!-e!Tz*{Eyu2>e{6q^GRh`j1Dm6}aQ8gu5i?QXT-=UA z5(wo2N8{@k(X!pnU4PJxdzUiVj`E=W!NoA)v1dfA8k^7pT?{%wP+o2kIZ0+0#HA0f zZBD+S6hTEV#`{}!HJ*>*;KGO*w^AH5n`6`;>+{}v*NC^aUy0|jzz|DYUF~y?hc@ru z;yxY>>DFaIaRBf(aV&>ug-EqXxLQa!+7HR%7ttu;Z|1|r*oKE#ro5YHGNee!idJEl zwVFsc(--yh38N#D(E}$Wf#M`NKtVk+7$`D0YAL=&^x>HpgPS@y$|`FYMqcq*)-AN+ zat}BUNAy@=jONOpg9PR)4t@iTQulQ}pBiekSFs_2$tiTsSjS+3_q^%gy3tMBCb; z)jpB{qzKC@(OHcYLINrbsR(EK$zf_jim>HwSVrkpWUQaSzvV7*sQ7;ZP*XIdN07x$tH>ve0|M(ucuPhvnqeV{&a& zJ{yI7AsG6JGU@^UnKU-S_Bh%C}FUsI1|;mkd^f z)S2<^DdIq(kgEZ(u((CCItYet#H^$;z-G^3CgT3wX={jCPQXq#4X&wv{*SCp;WS{z zb|+{UPap{=CnqF> z_ckGh5UWh5G&wyV*+WAUA{1oEt2j5I#M00)vmfkl`2cg@ht@nzzx?{^GqvrPHm^(> zXgSk}!}`4Ap``=mWqYd)MO4m3O+`rszHA_2y4&VXL>~xej!AWMvvQH%Y=E5HU*M`y z`Y#swee(MkH0O)^XzV|4(|5p_zF{tvj-83qN}IOV(|fw_?Nx^x8&@mUk1eHDPi>)u zA)~kTQ8j?;Kthgli%djsB^nkW&VNCg6(Z98XY|fhp9U%_(r-jOqkv*HZxj?c8?5&7#1HqjcjB$wlIH;3{Fz;a8@R@zd z#4Ep_slObhjM7PTCw4a6j)CJUXfW^qFW>MCO}^zWhTDG)ZuXh5Di651sR7hcNX_VL z5YsJySz{eo^`gtnz&Hx@Gbh~}ths{AZN3i0NCN^@#Z?};sw$`u?`jF)dmBC->k3hI z&%!vcaVyIq|FgDVKuX)TyRpjhAs>=^0}5BuRm>Y^%*3#)I>hUM*unfcIFy18tKs#t z=qv(&KG(1g&?F3;yvWMU&B}5+3s4&PGI;HW7S@EVAJow4Uq7LnzEEk#7x$3#)oR*$ z=~+7Rxfd5qoTeZD_0uz3(BpWwub~YXZ}!X?vHM1;vmy}PazBRLX_jQs18)G{id>U< zMars~z%dF7;Q)te2~`<+pQ%~+45^j`c)erlg-$7m#o&K-5{HIDT=u7}fG-uyg`UvMWQ-i+pN zl-XG!pZjW}qMR~-Hf81T*fvh$S}ZPEFwHJnq9%e9d_5WGP0%liS`&( z=RgKWdk3hG%HhZ@v1nwY&30B3Ey#gjz)DuGlq=^7yk-TmPRl-9Z7xdqsD{4!_XX@o zN7&;Iw3eq78as0#bLY<5wM6Z%0YV{&W4V_s(%nw?Tpazpr*93QbffkH?1lkSkGKSlpIJapT6C zk$apR%T*L*!|mI>WX~bGXVbGZx@H-U9*$-hTZ4i76#6CTb%uyCoKXnY1hlxAVJ711 zfIjC)NN&!7HpilnNsW=6bA-p4pM`MsIBbUOgxyPuKm&BEx_TFRu2o^nXY6RA7hiij zXr5{Rx>LV!%cl_Sysz?#H7}LTUBp$mp_+kXUW}2x9uDsX41N~B+hT!Cn&?1;LW@?? zRR;nz7xmA^F={Aodi#4150|Z%;;H_?^B_^fb%dCZ`l+0FL2pr3Q82lza`d6g?b}gS zE7dL{0>8(qg`}1MJ*rwT&pdd3)M3RPg)ba=iw4ZOVb@B86qDZy&0gX5IDrtd1;p(H zO(Z2GLAl_;sfR^w{=rbWGqrs78D^$*R8iB6gWjgN#Q}J_;lDE=e>2V&#rgX0o1y$r@$` zz)4T$>ZwCD3bv;@_b^Ja&4aJIv(!04>3$E*f8fF3F=N!x!cmTglPq6Q`q1(8${R;I zS=+ztgiqcn#JY)&Lv9`_TL!k&2FlCX6cboYoDv?F#efWlLe+uFT$LM8cm>p6!PLkYg^9?%CP=2R zq@eBTjoj!SjNTW?k(NF3Fgw-u)?QwJBaIXbDbX=msc|EcN<5;Zq9TZsQ$s9q$a`^O zE>2I44b6Fo$_mUcNb%KTW z+HrOJcYa8>W0BR|yH``H>F>lf4Q4uIr0V8ti((f;;68zwx(u96CffdXimYG4yqCHm2asD5*tfre6- z5m5f1AegCg$}@n{)%>RcsX$%_DLqBWFz+vVWZR*Mo3rR2PdCyG`2k8Up0wp42h#_C z3nl|4%7VcUCe&~+A(p^RJQ<(^35m%%%w{GN4G5EnYRGyVP+%wlr3kYdL#pZ`s;VL) zoSh>yHO3J`RU4PkQrFs@+aA7Jw7xZQ3T8em1Zw}x*00d=?bYRDd#kD9`CDnk@nv2l zKGB9`r$Gtexu;Q+sIjWo6jb%HIOEAa^*RUQoRlv&n6&isVZ&x-?OkE@rqBe(t<*ht zIJXi~+&~3sPZXj%L|M|%E&`zfmUX1%E>KR9*#T38K$%ierew7O$3H!-tyZ67SeJO~ z7w|DIdejY|Cb*vbu`EVVa2M zo%;a^JTX}Y1UWu#3UbnAzmlJ?B49j_-9$i+=nU5>n%$Tl+t1Okg^RDYfEUf`gTn#A zgwcMkcu2VAf~mhz$xmW<6FnuaNlGw+B6@2gRWk(|%E#G)&%gP`>KV4SgkC*z zm>%A`1xrw{L*v|+Uv#yesvc&Ov3xY%s&%23(*2Mq$wju(j3;TTPOrEugh$<)uFiW#?dnYL{R=lA z1J2`J>GikYqk`+FlV#BLj&uRxcK8i*>F9~m0Fn;9{SHOtji?qPPJ+M&7=hq591%k{ zH0)u52_O_1&76z_M8y=$9VMp4jgRvh=vAIM^ak1H&89w6COG=S=Ucj94n6bc8^zWW zUFlWrUHZqmwfo-McksEhb+ylb)NtTnQ~jFyTVYrny3oPMV(qYmE+y3s&EL$OklP~t zBD7}`~GYl%S7nbk(jldBD~Kh(+c#rU-=p-HmeBneoV> zXr@I(Bm{dXY39rW*--@G;gL|!5O_f`209vq80axYMIztUjKl?LBcgjmXJG6R@tv`< zVv2bW(|2gx9$C8~IKlm>0H3d?XfU1c8mh5%aVGDY!D+?CXv?`?UCoFVIZ>}c)oKF7 zQcV`#Ys92i0l=75#NRFA<3&HX*Qoll74+e+xDEw_un#G_Y!WXr(?ItH*(c4x(V=eu zCHHInOU7-9K(aK&Qs`wNz)h7BnY`zkP@-|;WC^6*FwFsLCx%;zNTLv6>At7enQe&P zm0mpZHd(8uZtEH+^nK^);2R+N$LaJZAJfpA9n|;6Ns1QTOZ1WV97uP11k!0Ll1%^% z#m-c+LX|KR!IluA^^9XasWO}7LB1FAIMc|?CX-GICj6|+m?3FKrtvq}{(B8JFJLng zyr^YoF9XrTbqKXG+o7Gs`+L- zjx}b9sAcG@EX?5BSjRMni}STm*&R%~eZ^V}{W`52g> zmd-zsEYnfr@-a?Aw$zJ+QEaoZNZkT@7J*>WV!S<6Z)Y0xKsEI!9bw*Ba!H}`F|*jO z7(BdjviLgIs(V;2MdMr;wrXy11fyzkIAjk)xGc@R1&mcFa~g(+nDHh;Zu28Zq+E_C z?y0I&N0@;@fHPi4U=4tU_kXN`VX5`U(8LGXCURV*0}EZy@F{c6+p2X8w`SdX2jeC? zWrcI33cm#+OU2)tz;&?27=Q{M0=ifUA&jRH_>;gxC~e9O)Oz}qRd-;`$UD?$@`Q2N zxf}-}rj{#TD*pRtK0QY{b7oNAnUkCr7>E&E_@Z5NA)RQh)ZASBoxj4cSJ)wRBD5kg zsNfNE8z5x1!XMnR9Zi87!_+$gp$Vc65c4%G-r$a!3tq5yMn-JcuENK}UL03=Tx1{{ zf^8%>q2~gb$8;XTG{lT_88$5t9-rDIY_=+|v>ca%NSe|)LXC+)bn%&}{GD^L`(`q( z$>NeXuwa}iBmVUBFSut2o|cW<>Z9@dQH8@PiaR7pyP)W@!`tHgV{$rll zy^G=}k5|H6%OwCt4{zIIjsuTvT|y(5-oki6P(!dmc6R4FoVi-68{DL#M1?vDiBg1` zGl-+G8*>4J?g7^rV$F{*jW(5j?g+~D|5l?({6&Vi$ANCRj zWG50H=RACv5yt$zC|}Jl%D3eU8)oRT6Ni*gt3(f_M-2E9u6)y7F*JD79P|27&VrX9 zbaEDCO9lR;^{d-kyP9WCI2A_W%*mw#11VXWOr@{hf())8lzbhD($P5#=4+%!b%0~QfPO0CYR!e+Xv5k8AK!yD zpb+mPmU8ldPNJd_)9KRpS5VB}Gkg@AKXTVt6Oy6JF+|Y*%#^G$Lhdlpa~E>Fp~^+@ zNEg3Nv+l&ESNO^FE;wYk4ZAeQUndZ6nDEjATQ+sE9s_+{vHnS5HxaEfQf0J?5dx!! zKugukcH3V8gG;Ccz24akBL$dhKrQ1EkS-ITG$u8{OP<8s5+7QM%ZxO*08z{EJAZ@H zdlgD5te<~EVaX{uz}+$!CCu}j9l<7<{EKD<#l=?TldA-vi!c~DFNzBY0rsY5KQ@c6 zOYeg-bUEcWz?XE8e*Oia)r`=p-}k(^P~;NWMxUAEsHkyXFgLb}W*5pAsuwyh2Zm0G zIv6EF4BA#Mo;dz+)qy*gfRf=x7Y3B@8OCadfAE^M<{19;vN5>2Ci8lIFxWyB&0Z3G zx(1zrVL82GBI137*_-k7CP+8{Cu_mL6oLmPw0QPr6V3Plr9}J#cKx9!az;GD8F7?Q zx}nzLPKw|bJ@>Ixdi9;dlsIz|R-8eJQG~ZY&KbFILJOw=m}S_#p^^uxV$W8_2i91Q zuml-eFeoA{H*F~%>39;Z0s1rLLCg;Z7NdcX z!Z29!!~{@EG*>@OO_Q{(t;k?A@JC^3wsn~0Vn-Y`Ass=uZ&=liez4`}33EorTSYEL zQ?F5@Xvo&td}+e|5doGh0?KSg22UnBG4N;b7_uLbV;n7fP*0fup-hX+x=-lTZ=W!m z-?FQLdSnmZ@mvR;`{E1h2|D`W8Om@>2n#ahMIfjhV1hX%j?*Irs!2h(kq@y_W!bOR_5h*Ef8T|1!n_1Fq397Y?C&yg zfvww_Z3vv~+l>o9|1p)Kim-Cf?3~wNo&^JVR~$0z3PI@6$8c{|;W*1hK|Mi0vQ|~| zdNOXx@SSplDcx)l#ABNd)rbAl7a0TuLnY~IF*vgUdkTa0=G9_|+?xLUn z_p9{;!f5Fo_cCzUw;@U}Jze$WCez;RLFXh~k5JT*5otV;#6S(Oi5}>qJ6NGmOx!q} z($pLwu_uiK2}v)NGN(=jE&s&o=}OPN^(JLZpV|SQBpUzV_N%M)#Ku`vwP-H&t)3`b zoL%60)*v?mJ&`Km8TwgWRPE40bO`|3W$=s8$N+MY8C5+^c7YNcm((QTD@;ksgxr{t zS`WH#3qu|9Ozbezb42I9nbuWhmZuh(O1 zX)`RG1@>ta$?-|uhg?r-cTJ)4x1q>`b9gW$lfx}O2s2#H_kO#{R25HRfzRU`x6_beQ>a%S3Kw?w zl#RnOdx$37_4^)l(AxF2RDhMd(FG%SFUd3Q4B@K7;_g5i<5Lr8(2xOm2UH1V4X(A` zNSFxE(i#VCtgnZ8<#($W73{^shp7TrlrWpbu)v0)+JQG-Gr97~Vp_WDLD(apyMaJN zt9bC9R82y}qH8HA@l`Y_7|Db>m`Or8!M_*^Q!gkfz(%KSV4fz!JZhMtGW^CVX5f0j zS^gHaZ9%A?Mq6D!AEgbl3(PXWx=F^_Bxv=FwCN;6xcZ9pd`-=_wSe_IHCF^M26Ys; zRZ#f)`LHG-4cL0b&@{?h@1TTf7$V^E$cq?(gY}ygE(q@*U32*FG6z~NV!2$>!iiM! z!p*^IhboTak}gXN$Ru>eUg)e7lUqcjIp zbJ}uh=jzo^!%Yi^!0@cufJ*a4|^=bEPQKrY~OjSseYk>>sr71R5dle z@)9C-QYT$>k+d!{wybd7OLaM*4(N^o1GP`LqZP1+YEnQPk2B}q;Qy>yB(iU$9-7$!hCHx21vgI|>ff!PAzzurf`O3AZs=w#rDcj18PC46|~QfjITW*7(?B}kAJB_;ganRbMN z(`(#+2}BRnDXh4}qQ1BUA9`uVKu$?={4GvS{E2`gxy`iuVBRPJfB?_2AiU?J4XTo= z*lWueaBKjC9>{$tV=m_a>+*hX1538C7g8u?ohjWloqCi68|91WB6G?n(}Qc)o2&yT zPWRWkuf%5)6O#KLev*b%P3_Ml1gmrrTs3@&%fS@RftKSk2s{KL9-VNgDCx$abR;*2 zJ2%&6%f-|tpoTfZ7!*y4!Fyn)khDxq9tsmd;O7%oZ}qTj-s!w*^;?f}7lFNUn7etJ zT4??DJv64~7D}^Er0C*Nqgc=gHeZOD>+m@<5tKA{4XeZWCI(HKLgS!tZ`e~uzP2`A z0ninH9G&>+!^fArdEm&|h6C|dFTLLsp#C!_?^@CcIoPe$^y=kM@svQ|prPcZ7GR?3 z#@yLJiUT2mEhw^v(;Tj@PR?NsFVnF@I9TQ{5=<>Dg4Ycm7dy z_uO8Yq{GZ*1~*xdFwkgeHjJlj&9bva=21y!Mhztbggrhc9xTAc#2xR_P}L|ye~qj3 zq#IC&%nPK0dhnFlOX=YAukhBh!>{jM?Yd=|%Qt=_q2Gw$&{ zcIuJUbi48hRgHH%mb0-t8Zv}x&fWu*HEAjhziA%bz4mc>_3guS`r}XD^*0`{epXGd>+e(H z+!{)pHi@!pX3%KoLb~h8$H4X9JbduoiwA+Lb@LLsW9=&HGh?Ds-U;o$r3+$F(W86y z0{`_R77dX*w*bR(h>ZStVVCxSu}50cc{1 z3@BkjD8ZTI0~5&+M2cY?r(^9h_D(WMDJ8ee8pR#v*Iv(Ylkro(C(0KYU4haQeYW+2MYp{1pZ z>E3srrgwE;!|Dgt(jxg@ENQELqWflx)+bre@|EUH+4@EGu??;XP1HZqpg_b|~Ff}~?!r}dItbXf4V{N?q z3mZN&fYLg<9UzF1VUz*=(0{Ym?oo$U z>atfv#nYgNaNK;vXtN8yvhQ2UM-H1lSI|?NcG5fV8!xUovhT$$?)rP`YOSsD*XPf8 zTw3E?cYq#Wzn!Mcksf$F%W|a;^%^}2OSb2*;J?4nSj>lX18&d&_Etr+zbi4Bd)ag^ zA4KuUHm45d+7E;vn&?stRM?&v1ek5Ql!=|(3K|sNtjo*Gux=01MIT3R7km+P|C$Y* z_O7~8-L*@nE_&B^>y<7%^kghFH3hb2t2KtxnQd{R-*AbP+)s%EDROp~+0K75sqGFK=@Vo_cjrQJP^DTw7?^#=}q{ld?$ zt~$Jl)~wrl*z?+>jVt%BZrplcmC%RSv$oc5t9^O}J^c9Qhvv|T$@89Ex*@l=ujNNH z+O`pt{rHVk=3FnPgJ7uz1u|X{<+>`k zp*n}bjH+?S#6us}5YKq2J(-wDX=0k$7?>hW`Y_ZG{FWxtY5mqZ1aSK$NW_f|ePINb zGqgfOl$Vy`0~}E5gp(hjj*GQEp8ke}XAk||aF}CBr9`jrD0WF8XGKOjL)qD3Hc!pi zWN(TcIAd!fz-<()iGPcSPdh*W7jIaQ<7DfFDdIN4ZI|!iMi|Tj;_x}D#FQD*(`GXqU3g!K0R>>EJ? zmQ2DozJP`Dy^CQV^P#AlZ!^+9JTL6TZNoE#O*3f6<--#NAlTmPK&0>@OWgQKk&!a+ zWUU-SKu4OMDGkXSBAgx1^(9>Tj5W^?9T!`oHNp1-;hoN+eb1U!BzHTkf(KrGg&(di z2H@#t;OS<_hA73se~)b8H`}5{_u}!AufJd5Yz_k4T~guUI?O{B^DJ9Uq=D>?M;l1+ z_Wau`{KeI0%CE42Aw+%=x02{0y~rS{jpq+7ESfgST2%ywdkVk3=v&PZQM}v_nq0P4 z15J)K&Y?pgvs6~f-LU(ln-+!ErZ?1KJp@^y1`X8cK9=_1_AWB-n;d!&iZ(ylV{Ude zn~B-fY!Y!c3UfZpfCu3OLwXh_5LqsbkB`}4{bG@;v*JOsFNsJkCY}d>iYLv;)X|I} zRScohm+?%wgdj(_qH#GFo>mq;k8Ynu)%HscdiC(zlyJj@zI|1kA4}0h9?E86VY%ig z$1C4S?j$UF7g_1WL={soDZRfg`n$E%T!-3R60l1p=GYGQO3lt)2tL@l98fWSMdRp& zIGUjS{ULv422b945Y~qI8k+Q+d_9;U3{xu0x3vkIToveEgEtq$Q%(-uV|dny^FIU7 zt}~%2Qw%)RZdhpPii%QWAtD*@qHX;YHM82xysTWe{{&@v^k}@y4jOrC*};_UN46hs zbJtiBA&CVWj21N=O?s{&73FHE&Nxcb8S^;2s0bWaeEa}MKTHfz+%ty^QA-`LU}aM2 zD>qZGk>(>s8Fklytw3^A>F_)6!z^5FZ9i#~txa@9*Z8@@VBoG9py06Bc;o^3cGO`*j^Gl$nzLK@&F zi#SDtB^y+RpU!XP zw-yG1EF+hvW;R=viX4k~NI_{s5<)VFM<<6!_M{N( zBYPgjOPzoo8(T_xQm?!F`r@#?Gtszd z+uF7thLnZ*vXAY1dX22&)od{D324Vj^X4zkW!*1JXR1hGf3c zLo?0A;v6TOB%n*-b=J`wfMHs_wJR}(K1M4adW_P`Fbm5YE>Y!#8v6SDMQi&}I5o=W zV4N~xdz1N9_l4>b!n-}i!0DSX`Hgb z$dOz;{rjUTx>G$E+|7h6Wrz~iaz%;8s+8GAL6X)v9w1M_QPk7Rw{r)BAtGbg&EHc= z)fh_7!*goqtyHMc9Z5#Y_w#8`wa9i7Yq{b5WDUMEmi8(<+mDHf2LX5Y!$oP?1C?xZ zB39`a2m+wOXCf05 zrB9neH{Yw!Te?m^|N1MOhr?(GQbeYm&{Cm(fo6a{)pvH}u8ldO=D=_&u zg`lzZ46^yrVl?Q*RhavOn@4okIYf*eone(@zrMs{Nk?|}z#-Y$Lwx9EJ;+hcZkQfK zX;2JwpfecySfzP+S})EVocq6qOgniDYRp{D{rd~KkBNtRs&Nr;Y25wvV&39I%m5zG zAXHc$@B)-}y#aUkxG~g?dm%&g z#wk$11gRt!ChVrR6Fdd0t6i_qb1%O^W2$eaJ_Vz<^~D#`lVeOX%(JRT>0O_f`b?ZK zszm5Gc{2SrnO=rz^y2rIZKHTorFp6dNEv8?2Ub*I;ulnncGB&7faTR_wh$ zh7N50zsPMs-ELeEQ1cZ`CpFX;81L_Frja5be#+YfJVg^w2_ ze|G6>SOmk>26HV9XR39`g*xbw7go|LzcM$>7a11Gb1i_^Gai>~575)FqaUY_$_@d! z@ng)_C0cWdKIo3p0o`DwfULF&G;i68m-bWTq}dcbc;rqejs-^I%b;y_`^+_f?X95t z2M%!d!#shPD^y}$b=TvMZ789vnbYB4n}9z|Pl48<@~S`d0Hs`axUELn;qDjbBIQ&U z$P{cfSp~QR$-oPb;?GlN?2D{WO<5PJ3EF`mNSx@tqe(YRpf~Vh|8#5^{c*amPIbo7 zFDI*L2M*MCTy}9a18$g&YQ&A#Tm{t#t~8bcn=pyQ5xoc<(yoD89HRp*DIU}c9tg+4 zZ0`^QT09tRX{E0lHZfqS5Bth^W`Q3?G!&E|DEK1Teul9#bleB0Q>At*=Rq)iJa4$r z;<=efb5w0_HJq?#U@!upq5+lPo$e7uMNUK-o_T@Iz~l;b3Rb9?NM8(K;yh?%rU9nX znmjhX&!qA<7h%cm7^e8q(Xf;D>FsucyRo{7IwG{L3jUKiEnV?ohh@AKg54c!R`c2k zUVZ`gCBj@{QCv;mxW2$31%iZRMi5t|P8w#%2Iv5fM{wHGtvm3gH6w03Xolf*l921* z$9A|d7`e_JsrB^#88w$^h;1}&S~Z<6wvMOYPZieRYdCkPv<3H@^~$_{NA|V6H#itQ z$a_LFH%~AcM@3cl&KgdRfa+r71uH@UxW=6QtjjgD5N znUR4{@kP74I;P?r7>3}E@up_m{xN)>1I1+AF}RRMey|*ugXtzJ=n?pdX#mAv<37p* zVQ}Cq4HOvHspZPvDnQ{63v*~ZMARa^@qk0=84ucE01^-8eFkn_GtrpX5jzIAYQ1qX z#H=C!1HW>p#Nia;0$wZExH?e1&bhDlK&|!4t`)T_wylY`2H+x{;B+!P_%rbp;s2#6 za-36+>&u^^6UhTxLui%jrQyy_m|l4?3+aXK4mzUWotm4fgDT_};P{YU(uDlRhIs&m z2^NNjkkAbroi%!TBCi#tOLVt9jXu_p-A>u+H||;Mb<)o#5H?ToZ5Qm4XU+hKhBhv6 zs3$SWt-{yEoQ)M#cmcH@z@`;4jP8O;p>hMwZobl?%oCV4LknONpPZP1H-E5W@L-M? ziK&Ch9C}Y0V`{JMAFz`NI_l8<^JwJhl%r#*hxc%Pi0#7<{N$lj)4i+n3{z!-K^fQ6&G9l+j<#zt=_tg zhTSx8-xkuFTg+L!|EaN5GHaF@WHK-Vau|5w+$zuFwG=3@%(xZgJ`Dm?x$t&@lB0Er z4jOm^n0uH73cU}4&2N{&>>eC>@W7xE8fsQ0PIwn-?oCrke{LqK5+}UkIwb()u(Mck08pboSM31@!5`h2RdCWa4}HD$wZQ3F!ph9>KFLSYK!`H~)u zL;>x>OnCSQT6euS9PT$l7znzd+D``EPJ?UV&ux>QiMHWkB6DF@g!;q;Ll4{5mWVTU zI%}#1d=>~TkiA@tIB@i_pvvD_4};A$3=KO*X#;qag=}X|>4#*>7n4;a!EMc)Yi>&p+STb70yYKGbU(QO+_2G&7RV@G2g3T-PR8R~6kQLYB?*fe& zgBw4#%%&fXjRuZIb@#S%nq2#TK^(jhF}QC*GfOSFjfGVJoIBzENyXHd`=)@}FIyjo z`1A76m?x}KWo0P-Zc&t>_Lh3X5h7;{)^ZSm_%0+{P#%rx-jC8(Lf9QT!qR>`XoXsh z%NX%CjXblQ5A`Tj*I|aDKv0PRuK2%p-rjmN9f6pf-kK}bFqo_q1gfe4BuG0($M^u0 zk?5}Cz0ROwkmk?KbUA>gV$`q#N%2#H5on10W>Ef5sI1W>yOmlzrPzr zp&+XOOuwW+D=}Pr($74ZiJd?}b3I}c#Bnh!e`9;!e4Y|>uBXQzm`UIGC(>`HhSsl< z+M;$~Ww*&h{@RKGQjSX;xzW48&StA>lbtRg3s78d@A7XSs{D1)tEv;Xg zCJ%ut3h6Zyi|-JnM;1{6ydd0gAW#uEeUg*;Tm(Dhq$+%UW?_?1D`+pyIOBhAed|gr z%{@XzV{sUuaD)Uu992x2&1M{H6Q;!58V^n(J%Hm)a2o(?qp2BJ7(9dRXxNisZNg19 z!{*Fm^yO%0gbXvcgPwcyP19?q$J5>yUf@$-gQUTO+zuz23A_ZTrQA7!JA?Ch3Jp%i zU=Pr~dOD1D!H)yp^Otrn7|(o6Rs+%FvdX}Nd@5RmiY56msI0in2RTH7 z2sac`l;(!_Qo_HlM)fwt%)~?t0Pvj*#(Q9M+qyFLy4qLjj!VC9!blRgl(SMD7)<@< zO)yo@5hs`JU5s=7$e0DT0+@~g1rj?%CLD}FR0qQZF$fP$i+hE;VA(>tSE z2n&;AA`JlVOB(=f$^(^}{Z6G+@eTlocME_oMkr%cnT#(>9}F84%O*-BpE{9g`pwJe zhkyO_!hUVdQe5n|k@}X7+1>{xeZA3#iw%6%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/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/qoi.c b/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/qoi.c new file mode 100644 index 00000000..d5962fc4 --- /dev/null +++ b/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/qoi.c @@ -0,0 +1,2 @@ +#define QOI_IMPLEMENTATION +#include "qoi.h" diff --git a/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/qoi.h b/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/qoi.h new file mode 100644 index 00000000..f2800b0c --- /dev/null +++ b/content/mods/E-rust-for-systems/topics/ffi/exercises/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/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/src/main.rs b/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/src/main.rs new file mode 100644 index 00000000..54568cf5 --- /dev/null +++ b/content/mods/E-rust-for-systems/topics/ffi/exercises/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/content/mods/E-rust-for-systems/topics/ffi/topic.toml b/content/mods/E-rust-for-systems/topics/ffi/topic.toml index 5f0d31e5..987e1873 100644 --- a/content/mods/E-rust-for-systems/topics/ffi/topic.toml +++ b/content/mods/E-rust-for-systems/topics/ffi/topic.toml @@ -22,6 +22,16 @@ includes = [ "README.md" ] +[[exercises]] +name = "QOI Bindgen" +path = "exercises/qoi-bindgen" +includes = [ + "Cargo.toml", + "Cargo.lock", + "src/**/*", + +] + [[exercises]] name = "TweetNaCl Bindgen" path = "exercises/tweetnacl-bindgen" @@ -29,5 +39,5 @@ includes = [ "Cargo.toml", "Cargo.lock", "src/**/*", - -] \ No newline at end of file + +] From a19e05ce8a7e58b599dc85753dd1bf5b939fa500 Mon Sep 17 00:00:00 2001 From: Marc Schoolderman Date: Thu, 30 Jan 2025 11:18:17 +0100 Subject: [PATCH 2/7] add modmod exercise_ref --- .../topics/ffi/exercises/qoi-bindgen/description.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/description.md b/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/description.md index c97f328c..466a3f87 100644 --- a/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/description.md +++ b/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/description.md @@ -8,7 +8,7 @@ In this exercise, we test if the image crate produces the same results when deco 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 +### #[modmod:exercise_ref] Generating bindings Prerequisites: - A C compiler is installed on the system @@ -33,7 +33,7 @@ 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. -### Inspecting our bindings +### #[modmod:exercise_ref] Inspecting our bindings In the generated `bindings.rs` file we find this signature for the `qoi_read` C function from QOI: @@ -70,7 +70,7 @@ Some observations: We will deal with the last point by writing a nice Rust wrapper *around* the generated bindings. -### Writing our wrapper +### #[modmod:exercise_ref] 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 @@ -123,7 +123,7 @@ running 1 test test tests::test_qoi_read ... ok ``` -### Freeing the pixel data +### #[modmod:exercise_ref] 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. @@ -149,7 +149,7 @@ To make sure someone using our wrapper does not forget to free the memory, we ca ``` - Now update the `read_qoi_image` function to return an instance of `MyImage`. -### Uninitialized memory +### #[modmod:exercise_ref] 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. 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. From 0b4873d1bc1b274677a45c435dcbc3d7ca944c10 Mon Sep 17 00:00:00 2001 From: Tamme Dittrich Date: Fri, 18 Jul 2025 10:04:44 +0200 Subject: [PATCH 3/7] Add missing files to topic.toml --- content/mods/E-rust-for-systems/topics/ffi/topic.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/content/mods/E-rust-for-systems/topics/ffi/topic.toml b/content/mods/E-rust-for-systems/topics/ffi/topic.toml index 987e1873..84f646a1 100644 --- a/content/mods/E-rust-for-systems/topics/ffi/topic.toml +++ b/content/mods/E-rust-for-systems/topics/ffi/topic.toml @@ -29,7 +29,9 @@ includes = [ "Cargo.toml", "Cargo.lock", "src/**/*", - + "*.qoi", + "*.c", + "*.h", ] [[exercises]] From 951d3e6792562e6e9f155c50971ccf0b53217d77 Mon Sep 17 00:00:00 2001 From: Tamme Dittrich Date: Fri, 18 Jul 2025 10:26:09 +0200 Subject: [PATCH 4/7] Reduce build time by reducing dependencies --- .../ffi/exercises/qoi-bindgen/Cargo.lock | 870 +----------------- .../ffi/exercises/qoi-bindgen/Cargo.toml | 2 +- .../ffi/exercises/qoi-bindgen/description.md | 2 +- 3 files changed, 3 insertions(+), 871 deletions(-) diff --git a/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/Cargo.lock b/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/Cargo.lock index 796df20a..9b0e7af3 100644 --- a/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/Cargo.lock +++ b/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "adler2" @@ -8,151 +8,36 @@ 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" @@ -162,64 +47,6 @@ 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" @@ -239,49 +66,6 @@ dependencies = [ "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" @@ -290,141 +74,17 @@ 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" @@ -435,69 +95,6 @@ dependencies = [ "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" @@ -507,24 +104,6 @@ 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" @@ -538,43 +117,6 @@ dependencies = [ "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" @@ -592,418 +134,8 @@ dependencies = [ "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/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/Cargo.toml b/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/Cargo.toml index e570fa02..62577cc9 100644 --- a/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/Cargo.toml +++ b/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/Cargo.toml @@ -4,5 +4,5 @@ version = "0.1.0" edition = "2021" [dependencies] -image = "0.25.5" +image = { version = "0.25.5", default-features = false, features = ["png", "qoi"] } libc = "0.2.167" diff --git a/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/description.md b/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/description.md index 466a3f87..c2d325f7 100644 --- a/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/description.md +++ b/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/description.md @@ -161,7 +161,7 @@ call void @llvm.memset.p0.i64(ptr noundef nonnull align 4 dereferenceable(10) %d %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 ``` -(The LLVM IR can be generated using `cargo rustc --bin qoi-bindgen --release -- --emit=llvm-ir`) +(The LLVM IR can be generated using `cargo rustc --bin qoi-bindgen --release -- --emit=llvm-ir=llvm-ir.ll`, then search for `@qoi_read` in `llvm-ir.ll`) The solution is to use `std::mem::MaybeUninit`: From cf0eb159b60caa925379ea93f5595481e660b37f Mon Sep 17 00:00:00 2001 From: Tamme Dittrich Date: Fri, 18 Jul 2025 13:38:05 +0200 Subject: [PATCH 5/7] Move from an image wraper to a slice wrapper --- .../ffi/exercises/qoi-bindgen/description.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/description.md b/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/description.md index c2d325f7..86dea6dd 100644 --- a/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/description.md +++ b/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/description.md @@ -128,26 +128,26 @@ When working with data from C, we are responsible for deallocating the memory on > The returned pixel data should be free()d after use. 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): +- First, create a wrapper `struct QoiSlice { ptr: NonNull, desc: qoi_desc }`, which holds the image buffer. +- Next, implement the `Drop` trait for `QoiSlice` to free the memory: ```rust - impl Drop for MyImage<'_> { + impl Drop for QoiSlice { 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: +- To make this `QoiSlice` usable in an `ImageBuffer`, we have to implement the `Deref` trait: ```rust - impl<'a> Deref for MyImage<'a> { - type Target = ImageBuffer, &'a [u8]>; - + impl Deref for QoiSlice { + type Target = [u8]; + fn deref(&self) -> &Self::Target { - &self.0 + todo!() // create a slice from the ptr and lenght using `slice::from_raw_parts()` } } ``` -- Now update the `read_qoi_image` function to return an instance of `MyImage`. +- Now update the `read_qoi_image` function to return an instance of `ImageBuffer, QoiSlice>`. ### #[modmod:exercise_ref] 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. From 49143911563985f6ac5dde5b4a84b45bea37876f Mon Sep 17 00:00:00 2001 From: Tamme Dittrich Date: Fri, 18 Jul 2025 13:38:05 +0200 Subject: [PATCH 6/7] Add section on unsafety comments --- .../topics/ffi/exercises/qoi-bindgen/description.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/description.md b/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/description.md index 86dea6dd..2b99d761 100644 --- a/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/description.md +++ b/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/description.md @@ -173,5 +173,15 @@ 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). +### #[modmod:exercise_ref] Safety documentation + +At the moment, the safety of your program relies on the context you have for the wrapped C library. +To ensure somebody modifying your library later does not break any of your assumptions you should always document what you assumed when writing the `unsafe code`. + +Add the following [clippy lint](https://rust-lang.github.io/rust-clippy/stable/index.html#multiple_unsafe_ops_per_block) to the top of your `lib.rs` and `main.rs`, run `cargo clippy` and document your assumptions: +```rust +#![deny(clippy::undocumented_unsafe_blocks)] +``` + ### 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. From 9c390f1f69a14e6b915911a412f6b38150fd4cb5 Mon Sep 17 00:00:00 2001 From: Tamme Dittrich Date: Fri, 18 Jul 2025 13:57:58 +0200 Subject: [PATCH 7/7] Add section on idiomatic code --- .../ffi/exercises/qoi-bindgen/description.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/description.md b/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/description.md index 2b99d761..f5a57b11 100644 --- a/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/description.md +++ b/content/mods/E-rust-for-systems/topics/ffi/exercises/qoi-bindgen/description.md @@ -183,5 +183,23 @@ Add the following [clippy lint](https://rust-lang.github.io/rust-clippy/stable/i #![deny(clippy::undocumented_unsafe_blocks)] ``` +### #[modmod:exercise_ref] Bonus: Idiomatic interface + +The current project is quite bare, you could improve that. + +#### Structure + +Currently, all your logic lives in `main.rs` where it cannot be used as a library. +Move your types and functions over to `lib.rs` and only expose the necessary functionality to the user. +Run `cargo doc --open` to inspect what a user would see. + +#### Error handling + +Currently, we use panicking to handle errors. +This is problematic since it does not offer the user to handle those errors. +Change `read_qoi_image()` to return a `Result` instead. +And change possible error cases to return an `Err()` instead of panicking. +Also consider which cases cannot possibly happen because of the guarantees you can make, and use `expect()` to panic in that case. + ### 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.