├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── pull_request_template.md ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── src ├── lib.rs └── main.rs └── tests ├── ascii.txt ├── image.jpg └── integration.rs /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Environment (please complete the following information):** 27 | - OS: [e.g. Windows 10] 28 | - Architecture: [e.g. x86_64] 29 | 30 | **Additional context** 31 | Add any other context about the problem here. 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | * **What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...) 2 | 3 | 4 | 5 | * **What is the current behavior?** (You can also link to an open issue here) 6 | 7 | 8 | 9 | * **What is the new behavior (if this is a feature change)?** 10 | 11 | 12 | 13 | * **Does this PR introduce a breaking change?** (What changes might users need to make in their application due to this PR?) 14 | 15 | 16 | 17 | * **Other information**: 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "adler" 7 | version = "1.0.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 10 | 11 | [[package]] 12 | name = "aligned-vec" 13 | version = "0.5.0" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" 16 | 17 | [[package]] 18 | name = "anstream" 19 | version = "0.6.13" 20 | source = "registry+https://github.com/rust-lang/crates.io-index" 21 | checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" 22 | dependencies = [ 23 | "anstyle", 24 | "anstyle-parse", 25 | "anstyle-query", 26 | "anstyle-wincon", 27 | "colorchoice", 28 | "utf8parse", 29 | ] 30 | 31 | [[package]] 32 | name = "anstyle" 33 | version = "1.0.6" 34 | source = "registry+https://github.com/rust-lang/crates.io-index" 35 | checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" 36 | 37 | [[package]] 38 | name = "anstyle-parse" 39 | version = "0.2.3" 40 | source = "registry+https://github.com/rust-lang/crates.io-index" 41 | checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" 42 | dependencies = [ 43 | "utf8parse", 44 | ] 45 | 46 | [[package]] 47 | name = "anstyle-query" 48 | version = "1.0.2" 49 | source = "registry+https://github.com/rust-lang/crates.io-index" 50 | checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" 51 | dependencies = [ 52 | "windows-sys", 53 | ] 54 | 55 | [[package]] 56 | name = "anstyle-wincon" 57 | version = "3.0.2" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" 60 | dependencies = [ 61 | "anstyle", 62 | "windows-sys", 63 | ] 64 | 65 | [[package]] 66 | name = "anyhow" 67 | version = "1.0.82" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" 70 | 71 | [[package]] 72 | name = "arbitrary" 73 | version = "1.3.2" 74 | source = "registry+https://github.com/rust-lang/crates.io-index" 75 | checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" 76 | 77 | [[package]] 78 | name = "arg_enum_proc_macro" 79 | version = "0.3.4" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" 82 | dependencies = [ 83 | "proc-macro2", 84 | "quote", 85 | "syn", 86 | ] 87 | 88 | [[package]] 89 | name = "arrayvec" 90 | version = "0.7.4" 91 | source = "registry+https://github.com/rust-lang/crates.io-index" 92 | checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" 93 | 94 | [[package]] 95 | name = "autocfg" 96 | version = "1.2.0" 97 | source = "registry+https://github.com/rust-lang/crates.io-index" 98 | checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" 99 | 100 | [[package]] 101 | name = "av1-grain" 102 | version = "0.2.3" 103 | source = "registry+https://github.com/rust-lang/crates.io-index" 104 | checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" 105 | dependencies = [ 106 | "anyhow", 107 | "arrayvec", 108 | "log", 109 | "nom", 110 | "num-rational", 111 | "v_frame", 112 | ] 113 | 114 | [[package]] 115 | name = "avif-serialize" 116 | version = "0.8.1" 117 | source = "registry+https://github.com/rust-lang/crates.io-index" 118 | checksum = "876c75a42f6364451a033496a14c44bffe41f5f4a8236f697391f11024e596d2" 119 | dependencies = [ 120 | "arrayvec", 121 | ] 122 | 123 | [[package]] 124 | name = "bit_field" 125 | version = "0.10.2" 126 | source = "registry+https://github.com/rust-lang/crates.io-index" 127 | checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" 128 | 129 | [[package]] 130 | name = "bitflags" 131 | version = "1.3.2" 132 | source = "registry+https://github.com/rust-lang/crates.io-index" 133 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 134 | 135 | [[package]] 136 | name = "bitstream-io" 137 | version = "2.2.0" 138 | source = "registry+https://github.com/rust-lang/crates.io-index" 139 | checksum = "06c9989a51171e2e81038ab168b6ae22886fe9ded214430dbb4f41c28cf176da" 140 | 141 | [[package]] 142 | name = "built" 143 | version = "0.7.2" 144 | source = "registry+https://github.com/rust-lang/crates.io-index" 145 | checksum = "41bfbdb21256b87a8b5e80fab81a8eed158178e812fd7ba451907518b2742f16" 146 | 147 | [[package]] 148 | name = "bumpalo" 149 | version = "3.16.0" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" 152 | 153 | [[package]] 154 | name = "bytemuck" 155 | version = "1.15.0" 156 | source = "registry+https://github.com/rust-lang/crates.io-index" 157 | checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15" 158 | 159 | [[package]] 160 | name = "byteorder" 161 | version = "1.5.0" 162 | source = "registry+https://github.com/rust-lang/crates.io-index" 163 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 164 | 165 | [[package]] 166 | name = "cc" 167 | version = "1.0.92" 168 | source = "registry+https://github.com/rust-lang/crates.io-index" 169 | checksum = "2678b2e3449475e95b0aa6f9b506a28e61b3dc8996592b983695e8ebb58a8b41" 170 | dependencies = [ 171 | "jobserver", 172 | "libc", 173 | ] 174 | 175 | [[package]] 176 | name = "cfg-expr" 177 | version = "0.15.8" 178 | source = "registry+https://github.com/rust-lang/crates.io-index" 179 | checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" 180 | dependencies = [ 181 | "smallvec", 182 | "target-lexicon", 183 | ] 184 | 185 | [[package]] 186 | name = "cfg-if" 187 | version = "1.0.0" 188 | source = "registry+https://github.com/rust-lang/crates.io-index" 189 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 190 | 191 | [[package]] 192 | name = "clap" 193 | version = "4.5.7" 194 | source = "registry+https://github.com/rust-lang/crates.io-index" 195 | checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" 196 | dependencies = [ 197 | "clap_builder", 198 | "clap_derive", 199 | ] 200 | 201 | [[package]] 202 | name = "clap_builder" 203 | version = "4.5.7" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" 206 | dependencies = [ 207 | "anstream", 208 | "anstyle", 209 | "clap_lex", 210 | "strsim", 211 | ] 212 | 213 | [[package]] 214 | name = "clap_derive" 215 | version = "4.5.5" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" 218 | dependencies = [ 219 | "heck", 220 | "proc-macro2", 221 | "quote", 222 | "syn", 223 | ] 224 | 225 | [[package]] 226 | name = "clap_lex" 227 | version = "0.7.0" 228 | source = "registry+https://github.com/rust-lang/crates.io-index" 229 | checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" 230 | 231 | [[package]] 232 | name = "color_quant" 233 | version = "1.1.0" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" 236 | 237 | [[package]] 238 | name = "colorchoice" 239 | version = "1.0.0" 240 | source = "registry+https://github.com/rust-lang/crates.io-index" 241 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 242 | 243 | [[package]] 244 | name = "console" 245 | version = "0.15.8" 246 | source = "registry+https://github.com/rust-lang/crates.io-index" 247 | checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" 248 | dependencies = [ 249 | "encode_unicode", 250 | "lazy_static", 251 | "libc", 252 | "unicode-width", 253 | "windows-sys", 254 | ] 255 | 256 | [[package]] 257 | name = "crc32fast" 258 | version = "1.4.0" 259 | source = "registry+https://github.com/rust-lang/crates.io-index" 260 | checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" 261 | dependencies = [ 262 | "cfg-if", 263 | ] 264 | 265 | [[package]] 266 | name = "crossbeam-deque" 267 | version = "0.8.5" 268 | source = "registry+https://github.com/rust-lang/crates.io-index" 269 | checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" 270 | dependencies = [ 271 | "crossbeam-epoch", 272 | "crossbeam-utils", 273 | ] 274 | 275 | [[package]] 276 | name = "crossbeam-epoch" 277 | version = "0.9.18" 278 | source = "registry+https://github.com/rust-lang/crates.io-index" 279 | checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" 280 | dependencies = [ 281 | "crossbeam-utils", 282 | ] 283 | 284 | [[package]] 285 | name = "crossbeam-utils" 286 | version = "0.8.19" 287 | source = "registry+https://github.com/rust-lang/crates.io-index" 288 | checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" 289 | 290 | [[package]] 291 | name = "crunchy" 292 | version = "0.2.2" 293 | source = "registry+https://github.com/rust-lang/crates.io-index" 294 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 295 | 296 | [[package]] 297 | name = "either" 298 | version = "1.11.0" 299 | source = "registry+https://github.com/rust-lang/crates.io-index" 300 | checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" 301 | 302 | [[package]] 303 | name = "encode_unicode" 304 | version = "0.3.6" 305 | source = "registry+https://github.com/rust-lang/crates.io-index" 306 | checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" 307 | 308 | [[package]] 309 | name = "equivalent" 310 | version = "1.0.1" 311 | source = "registry+https://github.com/rust-lang/crates.io-index" 312 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 313 | 314 | [[package]] 315 | name = "exr" 316 | version = "1.72.0" 317 | source = "registry+https://github.com/rust-lang/crates.io-index" 318 | checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4" 319 | dependencies = [ 320 | "bit_field", 321 | "flume", 322 | "half", 323 | "lebe", 324 | "miniz_oxide", 325 | "rayon-core", 326 | "smallvec", 327 | "zune-inflate", 328 | ] 329 | 330 | [[package]] 331 | name = "fdeflate" 332 | version = "0.3.4" 333 | source = "registry+https://github.com/rust-lang/crates.io-index" 334 | checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" 335 | dependencies = [ 336 | "simd-adler32", 337 | ] 338 | 339 | [[package]] 340 | name = "flate2" 341 | version = "1.0.28" 342 | source = "registry+https://github.com/rust-lang/crates.io-index" 343 | checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" 344 | dependencies = [ 345 | "crc32fast", 346 | "miniz_oxide", 347 | ] 348 | 349 | [[package]] 350 | name = "flume" 351 | version = "0.11.0" 352 | source = "registry+https://github.com/rust-lang/crates.io-index" 353 | checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" 354 | dependencies = [ 355 | "spin", 356 | ] 357 | 358 | [[package]] 359 | name = "getrandom" 360 | version = "0.2.14" 361 | source = "registry+https://github.com/rust-lang/crates.io-index" 362 | checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" 363 | dependencies = [ 364 | "cfg-if", 365 | "libc", 366 | "wasi", 367 | ] 368 | 369 | [[package]] 370 | name = "gif" 371 | version = "0.13.1" 372 | source = "registry+https://github.com/rust-lang/crates.io-index" 373 | checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" 374 | dependencies = [ 375 | "color_quant", 376 | "weezl", 377 | ] 378 | 379 | [[package]] 380 | name = "half" 381 | version = "2.4.1" 382 | source = "registry+https://github.com/rust-lang/crates.io-index" 383 | checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" 384 | dependencies = [ 385 | "cfg-if", 386 | "crunchy", 387 | ] 388 | 389 | [[package]] 390 | name = "hashbrown" 391 | version = "0.14.3" 392 | source = "registry+https://github.com/rust-lang/crates.io-index" 393 | checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" 394 | 395 | [[package]] 396 | name = "heck" 397 | version = "0.5.0" 398 | source = "registry+https://github.com/rust-lang/crates.io-index" 399 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 400 | 401 | [[package]] 402 | name = "image" 403 | version = "0.25.1" 404 | source = "registry+https://github.com/rust-lang/crates.io-index" 405 | checksum = "fd54d660e773627692c524beaad361aca785a4f9f5730ce91f42aabe5bce3d11" 406 | dependencies = [ 407 | "bytemuck", 408 | "byteorder", 409 | "color_quant", 410 | "exr", 411 | "gif", 412 | "image-webp", 413 | "num-traits", 414 | "png", 415 | "qoi", 416 | "ravif", 417 | "rayon", 418 | "rgb", 419 | "tiff", 420 | "zune-core", 421 | "zune-jpeg", 422 | ] 423 | 424 | [[package]] 425 | name = "image-webp" 426 | version = "0.1.1" 427 | source = "registry+https://github.com/rust-lang/crates.io-index" 428 | checksum = "7a84a25dcae3ac487bc24ef280f9e20c79c9b1a3e5e32cbed3041d1c514aa87c" 429 | dependencies = [ 430 | "byteorder", 431 | "thiserror", 432 | ] 433 | 434 | [[package]] 435 | name = "imgref" 436 | version = "1.10.1" 437 | source = "registry+https://github.com/rust-lang/crates.io-index" 438 | checksum = "44feda355f4159a7c757171a77de25daf6411e217b4cabd03bd6650690468126" 439 | 440 | [[package]] 441 | name = "indexmap" 442 | version = "2.2.6" 443 | source = "registry+https://github.com/rust-lang/crates.io-index" 444 | checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" 445 | dependencies = [ 446 | "equivalent", 447 | "hashbrown", 448 | ] 449 | 450 | [[package]] 451 | name = "indicatif" 452 | version = "0.17.8" 453 | source = "registry+https://github.com/rust-lang/crates.io-index" 454 | checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" 455 | dependencies = [ 456 | "console", 457 | "instant", 458 | "number_prefix", 459 | "portable-atomic", 460 | "unicode-width", 461 | ] 462 | 463 | [[package]] 464 | name = "instant" 465 | version = "0.1.12" 466 | source = "registry+https://github.com/rust-lang/crates.io-index" 467 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 468 | dependencies = [ 469 | "cfg-if", 470 | ] 471 | 472 | [[package]] 473 | name = "interpolate_name" 474 | version = "0.2.4" 475 | source = "registry+https://github.com/rust-lang/crates.io-index" 476 | checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" 477 | dependencies = [ 478 | "proc-macro2", 479 | "quote", 480 | "syn", 481 | ] 482 | 483 | [[package]] 484 | name = "itertools" 485 | version = "0.12.1" 486 | source = "registry+https://github.com/rust-lang/crates.io-index" 487 | checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" 488 | dependencies = [ 489 | "either", 490 | ] 491 | 492 | [[package]] 493 | name = "jobserver" 494 | version = "0.1.30" 495 | source = "registry+https://github.com/rust-lang/crates.io-index" 496 | checksum = "685a7d121ee3f65ae4fddd72b25a04bb36b6af81bc0828f7d5434c0fe60fa3a2" 497 | dependencies = [ 498 | "libc", 499 | ] 500 | 501 | [[package]] 502 | name = "jpeg-decoder" 503 | version = "0.3.1" 504 | source = "registry+https://github.com/rust-lang/crates.io-index" 505 | checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" 506 | 507 | [[package]] 508 | name = "lazy_static" 509 | version = "1.4.0" 510 | source = "registry+https://github.com/rust-lang/crates.io-index" 511 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 512 | 513 | [[package]] 514 | name = "lebe" 515 | version = "0.5.2" 516 | source = "registry+https://github.com/rust-lang/crates.io-index" 517 | checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" 518 | 519 | [[package]] 520 | name = "libc" 521 | version = "0.2.153" 522 | source = "registry+https://github.com/rust-lang/crates.io-index" 523 | checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" 524 | 525 | [[package]] 526 | name = "libfuzzer-sys" 527 | version = "0.4.7" 528 | source = "registry+https://github.com/rust-lang/crates.io-index" 529 | checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" 530 | dependencies = [ 531 | "arbitrary", 532 | "cc", 533 | "once_cell", 534 | ] 535 | 536 | [[package]] 537 | name = "lock_api" 538 | version = "0.4.11" 539 | source = "registry+https://github.com/rust-lang/crates.io-index" 540 | checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" 541 | dependencies = [ 542 | "autocfg", 543 | "scopeguard", 544 | ] 545 | 546 | [[package]] 547 | name = "log" 548 | version = "0.4.21" 549 | source = "registry+https://github.com/rust-lang/crates.io-index" 550 | checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" 551 | 552 | [[package]] 553 | name = "loop9" 554 | version = "0.1.5" 555 | source = "registry+https://github.com/rust-lang/crates.io-index" 556 | checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" 557 | dependencies = [ 558 | "imgref", 559 | ] 560 | 561 | [[package]] 562 | name = "maybe-rayon" 563 | version = "0.1.1" 564 | source = "registry+https://github.com/rust-lang/crates.io-index" 565 | checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" 566 | dependencies = [ 567 | "cfg-if", 568 | "rayon", 569 | ] 570 | 571 | [[package]] 572 | name = "memchr" 573 | version = "2.7.2" 574 | source = "registry+https://github.com/rust-lang/crates.io-index" 575 | checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" 576 | 577 | [[package]] 578 | name = "minimal-lexical" 579 | version = "0.2.1" 580 | source = "registry+https://github.com/rust-lang/crates.io-index" 581 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 582 | 583 | [[package]] 584 | name = "miniz_oxide" 585 | version = "0.7.3" 586 | source = "registry+https://github.com/rust-lang/crates.io-index" 587 | checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" 588 | dependencies = [ 589 | "adler", 590 | "simd-adler32", 591 | ] 592 | 593 | [[package]] 594 | name = "new_debug_unreachable" 595 | version = "1.0.6" 596 | source = "registry+https://github.com/rust-lang/crates.io-index" 597 | checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" 598 | 599 | [[package]] 600 | name = "nom" 601 | version = "7.1.3" 602 | source = "registry+https://github.com/rust-lang/crates.io-index" 603 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 604 | dependencies = [ 605 | "memchr", 606 | "minimal-lexical", 607 | ] 608 | 609 | [[package]] 610 | name = "noop_proc_macro" 611 | version = "0.3.0" 612 | source = "registry+https://github.com/rust-lang/crates.io-index" 613 | checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" 614 | 615 | [[package]] 616 | name = "num-bigint" 617 | version = "0.4.4" 618 | source = "registry+https://github.com/rust-lang/crates.io-index" 619 | checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" 620 | dependencies = [ 621 | "autocfg", 622 | "num-integer", 623 | "num-traits", 624 | ] 625 | 626 | [[package]] 627 | name = "num-derive" 628 | version = "0.4.2" 629 | source = "registry+https://github.com/rust-lang/crates.io-index" 630 | checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" 631 | dependencies = [ 632 | "proc-macro2", 633 | "quote", 634 | "syn", 635 | ] 636 | 637 | [[package]] 638 | name = "num-integer" 639 | version = "0.1.46" 640 | source = "registry+https://github.com/rust-lang/crates.io-index" 641 | checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" 642 | dependencies = [ 643 | "num-traits", 644 | ] 645 | 646 | [[package]] 647 | name = "num-rational" 648 | version = "0.4.1" 649 | source = "registry+https://github.com/rust-lang/crates.io-index" 650 | checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" 651 | dependencies = [ 652 | "autocfg", 653 | "num-bigint", 654 | "num-integer", 655 | "num-traits", 656 | ] 657 | 658 | [[package]] 659 | name = "num-traits" 660 | version = "0.2.18" 661 | source = "registry+https://github.com/rust-lang/crates.io-index" 662 | checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" 663 | dependencies = [ 664 | "autocfg", 665 | ] 666 | 667 | [[package]] 668 | name = "number_prefix" 669 | version = "0.4.0" 670 | source = "registry+https://github.com/rust-lang/crates.io-index" 671 | checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" 672 | 673 | [[package]] 674 | name = "once_cell" 675 | version = "1.19.0" 676 | source = "registry+https://github.com/rust-lang/crates.io-index" 677 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" 678 | 679 | [[package]] 680 | name = "paste" 681 | version = "1.0.14" 682 | source = "registry+https://github.com/rust-lang/crates.io-index" 683 | checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" 684 | 685 | [[package]] 686 | name = "pkg-config" 687 | version = "0.3.30" 688 | source = "registry+https://github.com/rust-lang/crates.io-index" 689 | checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" 690 | 691 | [[package]] 692 | name = "png" 693 | version = "0.17.13" 694 | source = "registry+https://github.com/rust-lang/crates.io-index" 695 | checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" 696 | dependencies = [ 697 | "bitflags", 698 | "crc32fast", 699 | "fdeflate", 700 | "flate2", 701 | "miniz_oxide", 702 | ] 703 | 704 | [[package]] 705 | name = "portable-atomic" 706 | version = "1.6.0" 707 | source = "registry+https://github.com/rust-lang/crates.io-index" 708 | checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" 709 | 710 | [[package]] 711 | name = "ppv-lite86" 712 | version = "0.2.17" 713 | source = "registry+https://github.com/rust-lang/crates.io-index" 714 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 715 | 716 | [[package]] 717 | name = "proc-macro2" 718 | version = "1.0.79" 719 | source = "registry+https://github.com/rust-lang/crates.io-index" 720 | checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" 721 | dependencies = [ 722 | "unicode-ident", 723 | ] 724 | 725 | [[package]] 726 | name = "profiling" 727 | version = "1.0.15" 728 | source = "registry+https://github.com/rust-lang/crates.io-index" 729 | checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58" 730 | dependencies = [ 731 | "profiling-procmacros", 732 | ] 733 | 734 | [[package]] 735 | name = "profiling-procmacros" 736 | version = "1.0.15" 737 | source = "registry+https://github.com/rust-lang/crates.io-index" 738 | checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd" 739 | dependencies = [ 740 | "quote", 741 | "syn", 742 | ] 743 | 744 | [[package]] 745 | name = "qoi" 746 | version = "0.4.1" 747 | source = "registry+https://github.com/rust-lang/crates.io-index" 748 | checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" 749 | dependencies = [ 750 | "bytemuck", 751 | ] 752 | 753 | [[package]] 754 | name = "quick-error" 755 | version = "2.0.1" 756 | source = "registry+https://github.com/rust-lang/crates.io-index" 757 | checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" 758 | 759 | [[package]] 760 | name = "quote" 761 | version = "1.0.35" 762 | source = "registry+https://github.com/rust-lang/crates.io-index" 763 | checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" 764 | dependencies = [ 765 | "proc-macro2", 766 | ] 767 | 768 | [[package]] 769 | name = "rand" 770 | version = "0.8.5" 771 | source = "registry+https://github.com/rust-lang/crates.io-index" 772 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 773 | dependencies = [ 774 | "libc", 775 | "rand_chacha", 776 | "rand_core", 777 | ] 778 | 779 | [[package]] 780 | name = "rand_chacha" 781 | version = "0.3.1" 782 | source = "registry+https://github.com/rust-lang/crates.io-index" 783 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 784 | dependencies = [ 785 | "ppv-lite86", 786 | "rand_core", 787 | ] 788 | 789 | [[package]] 790 | name = "rand_core" 791 | version = "0.6.4" 792 | source = "registry+https://github.com/rust-lang/crates.io-index" 793 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 794 | dependencies = [ 795 | "getrandom", 796 | ] 797 | 798 | [[package]] 799 | name = "rav1e" 800 | version = "0.7.1" 801 | source = "registry+https://github.com/rust-lang/crates.io-index" 802 | checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" 803 | dependencies = [ 804 | "arbitrary", 805 | "arg_enum_proc_macro", 806 | "arrayvec", 807 | "av1-grain", 808 | "bitstream-io", 809 | "built", 810 | "cfg-if", 811 | "interpolate_name", 812 | "itertools", 813 | "libc", 814 | "libfuzzer-sys", 815 | "log", 816 | "maybe-rayon", 817 | "new_debug_unreachable", 818 | "noop_proc_macro", 819 | "num-derive", 820 | "num-traits", 821 | "once_cell", 822 | "paste", 823 | "profiling", 824 | "rand", 825 | "rand_chacha", 826 | "simd_helpers", 827 | "system-deps", 828 | "thiserror", 829 | "v_frame", 830 | "wasm-bindgen", 831 | ] 832 | 833 | [[package]] 834 | name = "ravif" 835 | version = "0.11.5" 836 | source = "registry+https://github.com/rust-lang/crates.io-index" 837 | checksum = "bc13288f5ab39e6d7c9d501759712e6969fcc9734220846fc9ed26cae2cc4234" 838 | dependencies = [ 839 | "avif-serialize", 840 | "imgref", 841 | "loop9", 842 | "quick-error", 843 | "rav1e", 844 | "rayon", 845 | "rgb", 846 | ] 847 | 848 | [[package]] 849 | name = "rayon" 850 | version = "1.10.0" 851 | source = "registry+https://github.com/rust-lang/crates.io-index" 852 | checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" 853 | dependencies = [ 854 | "either", 855 | "rayon-core", 856 | ] 857 | 858 | [[package]] 859 | name = "rayon-core" 860 | version = "1.12.1" 861 | source = "registry+https://github.com/rust-lang/crates.io-index" 862 | checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" 863 | dependencies = [ 864 | "crossbeam-deque", 865 | "crossbeam-utils", 866 | ] 867 | 868 | [[package]] 869 | name = "rgb" 870 | version = "0.8.37" 871 | source = "registry+https://github.com/rust-lang/crates.io-index" 872 | checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8" 873 | dependencies = [ 874 | "bytemuck", 875 | ] 876 | 877 | [[package]] 878 | name = "rustii" 879 | version = "0.1.2" 880 | dependencies = [ 881 | "clap", 882 | "image", 883 | "indicatif", 884 | "miniz_oxide", 885 | ] 886 | 887 | [[package]] 888 | name = "scopeguard" 889 | version = "1.2.0" 890 | source = "registry+https://github.com/rust-lang/crates.io-index" 891 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 892 | 893 | [[package]] 894 | name = "serde" 895 | version = "1.0.197" 896 | source = "registry+https://github.com/rust-lang/crates.io-index" 897 | checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" 898 | dependencies = [ 899 | "serde_derive", 900 | ] 901 | 902 | [[package]] 903 | name = "serde_derive" 904 | version = "1.0.197" 905 | source = "registry+https://github.com/rust-lang/crates.io-index" 906 | checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" 907 | dependencies = [ 908 | "proc-macro2", 909 | "quote", 910 | "syn", 911 | ] 912 | 913 | [[package]] 914 | name = "serde_spanned" 915 | version = "0.6.5" 916 | source = "registry+https://github.com/rust-lang/crates.io-index" 917 | checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" 918 | dependencies = [ 919 | "serde", 920 | ] 921 | 922 | [[package]] 923 | name = "simd-adler32" 924 | version = "0.3.7" 925 | source = "registry+https://github.com/rust-lang/crates.io-index" 926 | checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" 927 | 928 | [[package]] 929 | name = "simd_helpers" 930 | version = "0.1.0" 931 | source = "registry+https://github.com/rust-lang/crates.io-index" 932 | checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" 933 | dependencies = [ 934 | "quote", 935 | ] 936 | 937 | [[package]] 938 | name = "smallvec" 939 | version = "1.13.2" 940 | source = "registry+https://github.com/rust-lang/crates.io-index" 941 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 942 | 943 | [[package]] 944 | name = "spin" 945 | version = "0.9.8" 946 | source = "registry+https://github.com/rust-lang/crates.io-index" 947 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 948 | dependencies = [ 949 | "lock_api", 950 | ] 951 | 952 | [[package]] 953 | name = "strsim" 954 | version = "0.11.1" 955 | source = "registry+https://github.com/rust-lang/crates.io-index" 956 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 957 | 958 | [[package]] 959 | name = "syn" 960 | version = "2.0.52" 961 | source = "registry+https://github.com/rust-lang/crates.io-index" 962 | checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" 963 | dependencies = [ 964 | "proc-macro2", 965 | "quote", 966 | "unicode-ident", 967 | ] 968 | 969 | [[package]] 970 | name = "system-deps" 971 | version = "6.2.2" 972 | source = "registry+https://github.com/rust-lang/crates.io-index" 973 | checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" 974 | dependencies = [ 975 | "cfg-expr", 976 | "heck", 977 | "pkg-config", 978 | "toml", 979 | "version-compare", 980 | ] 981 | 982 | [[package]] 983 | name = "target-lexicon" 984 | version = "0.12.14" 985 | source = "registry+https://github.com/rust-lang/crates.io-index" 986 | checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" 987 | 988 | [[package]] 989 | name = "thiserror" 990 | version = "1.0.58" 991 | source = "registry+https://github.com/rust-lang/crates.io-index" 992 | checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" 993 | dependencies = [ 994 | "thiserror-impl", 995 | ] 996 | 997 | [[package]] 998 | name = "thiserror-impl" 999 | version = "1.0.58" 1000 | source = "registry+https://github.com/rust-lang/crates.io-index" 1001 | checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" 1002 | dependencies = [ 1003 | "proc-macro2", 1004 | "quote", 1005 | "syn", 1006 | ] 1007 | 1008 | [[package]] 1009 | name = "tiff" 1010 | version = "0.9.1" 1011 | source = "registry+https://github.com/rust-lang/crates.io-index" 1012 | checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" 1013 | dependencies = [ 1014 | "flate2", 1015 | "jpeg-decoder", 1016 | "weezl", 1017 | ] 1018 | 1019 | [[package]] 1020 | name = "toml" 1021 | version = "0.8.12" 1022 | source = "registry+https://github.com/rust-lang/crates.io-index" 1023 | checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" 1024 | dependencies = [ 1025 | "serde", 1026 | "serde_spanned", 1027 | "toml_datetime", 1028 | "toml_edit", 1029 | ] 1030 | 1031 | [[package]] 1032 | name = "toml_datetime" 1033 | version = "0.6.5" 1034 | source = "registry+https://github.com/rust-lang/crates.io-index" 1035 | checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" 1036 | dependencies = [ 1037 | "serde", 1038 | ] 1039 | 1040 | [[package]] 1041 | name = "toml_edit" 1042 | version = "0.22.9" 1043 | source = "registry+https://github.com/rust-lang/crates.io-index" 1044 | checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" 1045 | dependencies = [ 1046 | "indexmap", 1047 | "serde", 1048 | "serde_spanned", 1049 | "toml_datetime", 1050 | "winnow", 1051 | ] 1052 | 1053 | [[package]] 1054 | name = "unicode-ident" 1055 | version = "1.0.12" 1056 | source = "registry+https://github.com/rust-lang/crates.io-index" 1057 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 1058 | 1059 | [[package]] 1060 | name = "unicode-width" 1061 | version = "0.1.11" 1062 | source = "registry+https://github.com/rust-lang/crates.io-index" 1063 | checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" 1064 | 1065 | [[package]] 1066 | name = "utf8parse" 1067 | version = "0.2.1" 1068 | source = "registry+https://github.com/rust-lang/crates.io-index" 1069 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 1070 | 1071 | [[package]] 1072 | name = "v_frame" 1073 | version = "0.3.8" 1074 | source = "registry+https://github.com/rust-lang/crates.io-index" 1075 | checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b" 1076 | dependencies = [ 1077 | "aligned-vec", 1078 | "num-traits", 1079 | "wasm-bindgen", 1080 | ] 1081 | 1082 | [[package]] 1083 | name = "version-compare" 1084 | version = "0.2.0" 1085 | source = "registry+https://github.com/rust-lang/crates.io-index" 1086 | checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" 1087 | 1088 | [[package]] 1089 | name = "wasi" 1090 | version = "0.11.0+wasi-snapshot-preview1" 1091 | source = "registry+https://github.com/rust-lang/crates.io-index" 1092 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1093 | 1094 | [[package]] 1095 | name = "wasm-bindgen" 1096 | version = "0.2.92" 1097 | source = "registry+https://github.com/rust-lang/crates.io-index" 1098 | checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" 1099 | dependencies = [ 1100 | "cfg-if", 1101 | "wasm-bindgen-macro", 1102 | ] 1103 | 1104 | [[package]] 1105 | name = "wasm-bindgen-backend" 1106 | version = "0.2.92" 1107 | source = "registry+https://github.com/rust-lang/crates.io-index" 1108 | checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" 1109 | dependencies = [ 1110 | "bumpalo", 1111 | "log", 1112 | "once_cell", 1113 | "proc-macro2", 1114 | "quote", 1115 | "syn", 1116 | "wasm-bindgen-shared", 1117 | ] 1118 | 1119 | [[package]] 1120 | name = "wasm-bindgen-macro" 1121 | version = "0.2.92" 1122 | source = "registry+https://github.com/rust-lang/crates.io-index" 1123 | checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" 1124 | dependencies = [ 1125 | "quote", 1126 | "wasm-bindgen-macro-support", 1127 | ] 1128 | 1129 | [[package]] 1130 | name = "wasm-bindgen-macro-support" 1131 | version = "0.2.92" 1132 | source = "registry+https://github.com/rust-lang/crates.io-index" 1133 | checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" 1134 | dependencies = [ 1135 | "proc-macro2", 1136 | "quote", 1137 | "syn", 1138 | "wasm-bindgen-backend", 1139 | "wasm-bindgen-shared", 1140 | ] 1141 | 1142 | [[package]] 1143 | name = "wasm-bindgen-shared" 1144 | version = "0.2.92" 1145 | source = "registry+https://github.com/rust-lang/crates.io-index" 1146 | checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" 1147 | 1148 | [[package]] 1149 | name = "weezl" 1150 | version = "0.1.8" 1151 | source = "registry+https://github.com/rust-lang/crates.io-index" 1152 | checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" 1153 | 1154 | [[package]] 1155 | name = "windows-sys" 1156 | version = "0.52.0" 1157 | source = "registry+https://github.com/rust-lang/crates.io-index" 1158 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 1159 | dependencies = [ 1160 | "windows-targets", 1161 | ] 1162 | 1163 | [[package]] 1164 | name = "windows-targets" 1165 | version = "0.52.5" 1166 | source = "registry+https://github.com/rust-lang/crates.io-index" 1167 | checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" 1168 | dependencies = [ 1169 | "windows_aarch64_gnullvm", 1170 | "windows_aarch64_msvc", 1171 | "windows_i686_gnu", 1172 | "windows_i686_gnullvm", 1173 | "windows_i686_msvc", 1174 | "windows_x86_64_gnu", 1175 | "windows_x86_64_gnullvm", 1176 | "windows_x86_64_msvc", 1177 | ] 1178 | 1179 | [[package]] 1180 | name = "windows_aarch64_gnullvm" 1181 | version = "0.52.5" 1182 | source = "registry+https://github.com/rust-lang/crates.io-index" 1183 | checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" 1184 | 1185 | [[package]] 1186 | name = "windows_aarch64_msvc" 1187 | version = "0.52.5" 1188 | source = "registry+https://github.com/rust-lang/crates.io-index" 1189 | checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" 1190 | 1191 | [[package]] 1192 | name = "windows_i686_gnu" 1193 | version = "0.52.5" 1194 | source = "registry+https://github.com/rust-lang/crates.io-index" 1195 | checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" 1196 | 1197 | [[package]] 1198 | name = "windows_i686_gnullvm" 1199 | version = "0.52.5" 1200 | source = "registry+https://github.com/rust-lang/crates.io-index" 1201 | checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" 1202 | 1203 | [[package]] 1204 | name = "windows_i686_msvc" 1205 | version = "0.52.5" 1206 | source = "registry+https://github.com/rust-lang/crates.io-index" 1207 | checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" 1208 | 1209 | [[package]] 1210 | name = "windows_x86_64_gnu" 1211 | version = "0.52.5" 1212 | source = "registry+https://github.com/rust-lang/crates.io-index" 1213 | checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" 1214 | 1215 | [[package]] 1216 | name = "windows_x86_64_gnullvm" 1217 | version = "0.52.5" 1218 | source = "registry+https://github.com/rust-lang/crates.io-index" 1219 | checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" 1220 | 1221 | [[package]] 1222 | name = "windows_x86_64_msvc" 1223 | version = "0.52.5" 1224 | source = "registry+https://github.com/rust-lang/crates.io-index" 1225 | checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" 1226 | 1227 | [[package]] 1228 | name = "winnow" 1229 | version = "0.6.6" 1230 | source = "registry+https://github.com/rust-lang/crates.io-index" 1231 | checksum = "f0c976aaaa0e1f90dbb21e9587cdaf1d9679a1cde8875c0d6bd83ab96a208352" 1232 | dependencies = [ 1233 | "memchr", 1234 | ] 1235 | 1236 | [[package]] 1237 | name = "zune-core" 1238 | version = "0.4.12" 1239 | source = "registry+https://github.com/rust-lang/crates.io-index" 1240 | checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" 1241 | 1242 | [[package]] 1243 | name = "zune-inflate" 1244 | version = "0.2.54" 1245 | source = "registry+https://github.com/rust-lang/crates.io-index" 1246 | checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" 1247 | dependencies = [ 1248 | "simd-adler32", 1249 | ] 1250 | 1251 | [[package]] 1252 | name = "zune-jpeg" 1253 | version = "0.4.11" 1254 | source = "registry+https://github.com/rust-lang/crates.io-index" 1255 | checksum = "ec866b44a2a1fd6133d363f073ca1b179f438f99e7e5bfb1e33f7181facfe448" 1256 | dependencies = [ 1257 | "zune-core", 1258 | ] 1259 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rustii" 3 | version = "0.1.2" 4 | edition = "2021" 5 | description = "Converts images to ASCII art" 6 | license = "MIT" 7 | repository = "https://github.com/ndr3www/rustii/tree/main" 8 | readme = "README.md" 9 | keywords = ["ascii", "ascii-art", "cli", "text", "art"] 10 | categories = ["command-line-utilities", "computer-vision", "encoding", "multimedia::images"] 11 | 12 | [dependencies] 13 | clap = { version = "4.5.7", features = ["derive"] } 14 | image = "0.25.1" 15 | miniz_oxide = "0.7.3" 16 | indicatif = "0.17.8" 17 | 18 | [lints.clippy] 19 | suspicious = "warn" 20 | complexity = "warn" 21 | perf = "warn" 22 | style = "warn" 23 | pedantic = "warn" 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 ndr3www 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | Crates.io Version 4 | Crates.io Downloads 5 | 6 |

7 | 8 | # Installation 9 | 10 | ## Through cargo 11 | `cargo install rustii` 12 | 13 | ## Manually 14 | 15 | ### Linux 16 | Just download the appropriate binary from [latest release](https://github.com/ndr3www/rustii/releases/latest) and copy it to a directory specified in your `$PATH`, for example: 17 | 18 | `sudo cp rustii /usr/bin` 19 | 20 | ### Windows 21 | 1. Download **rustii.exe** from [latest release](https://github.com/ndr3www/rustii/releases/latest) 22 | 2. Create a folder named **rustii** anywhere you like 23 | 3. Copy **rustii.exe** to the newly created folder 24 | 4. Type `environment` in your search bar and hit `Enter` 25 | 5. Click the `Environment Variables...` button 26 | 6. Select **Path** variable and click `Edit...` 27 | 7. Click `New` and then `Browse...`, then find and select the **rustii** folder 28 | 8. Click `OK` and you're done! 29 | # Usage 30 | Basically `rustii` has 2 commands: 31 | - `render` - generates ASCII art from a specified image 32 | - `open` - prints specified ASCII art to the terminal/console 33 | 34 | `rustii` compresses generated ASCII art file by default, so if you want to get the raw ASCII art, you can simply redirect the output of the `open` command, for example: `rustii open ascii.txt > raw_ascii.txt` 35 | 36 | Type `rustii --help` or `rustii -h` to get more details 37 | 38 | # Examples 39 | `rustii render avatar.jpg --output ascii.txt --scale 0.22 0.09 --contrast 10` 40 | ![image](https://github.com/ndr3www/rustii/assets/164680506/75be086c-67c5-4e84-a3f3-3c65d4af80ec) 41 | 42 | `rustii render catedral.jpg --output ascii.txt --scale 0.13 0.053` 43 | ![image(1)](https://github.com/ndr3www/rustii/assets/164680506/26d32faf-1748-4c36-b6f7-525d30b38fe2) 44 | 45 | `rustii render woman.jpg --output ascii.txt --scale 0.09 0.032 --contrast -5` 46 | ![image(2)](https://github.com/ndr3www/rustii/assets/164680506/4c7d2e76-3536-4e92-9e4d-98cc1d1a502a) 47 | 48 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::missing_errors_doc)] 2 | 3 | use std::process; 4 | use std::fs::File; 5 | use std::io::prelude::*; 6 | use std::time::Duration; 7 | use std::str; 8 | 9 | use clap::{Parser, Subcommand}; 10 | use image::{imageops::FilterType, io::Reader as ImageReader, DynamicImage, GenericImageView, Pixel}; 11 | use miniz_oxide::deflate::compress_to_vec; 12 | use miniz_oxide::inflate::decompress_to_vec; 13 | use indicatif::{ProgressBar, ProgressStyle}; 14 | 15 | pub const APP_NAME: &str = env!("CARGO_PKG_NAME"); 16 | 17 | const GRAYSCALE: &str = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\"^`'. "; 18 | 19 | const SPINNER_TICK: u64 = 80; 20 | 21 | /// Handles parsing of command line arguments 22 | #[derive(Parser)] 23 | #[command(version, about, long_about = None)] 24 | #[command(propagate_version = true)] 25 | pub struct Cli { 26 | #[command(subcommand)] 27 | command: Commands 28 | } 29 | 30 | impl Cli { 31 | #![allow(clippy::must_use_candidate)] 32 | pub fn get_command(&self) -> &Commands { 33 | &self.command 34 | } 35 | } 36 | 37 | /// List of available commands and options 38 | #[derive(Subcommand)] 39 | pub enum Commands { 40 | /// Render specified image file to ASCII art 41 | Render { 42 | /// Image file to be rendered 43 | input_file_path: String, 44 | /// Produced ASCII art file 45 | #[arg(short, long, value_name = "OUTPUT_FILE_PATH")] 46 | output: String, 47 | /// Scale of the produced ASCII art in order: 48 | #[arg(short, long, value_name = "FLOAT", value_parser, num_args = 2, value_delimiter = ' ')] 49 | #[arg(default_values_t = [1.0, 1.0])] 50 | scale: Vec, 51 | /// Adjust the contrast of the produced ASCII art, negative values decrease the contrast and positive increase it 52 | #[arg(short, long, value_name = "FLOAT")] 53 | #[arg(value_parser = clap::value_parser!(f32))] 54 | #[arg(default_value_t = 0.0)] 55 | #[arg(allow_hyphen_values = true)] 56 | contrast: f32 57 | }, 58 | /// Open specified ASCII art file in terminal 59 | Open { 60 | input_file_path: String 61 | } 62 | } 63 | 64 | /// Handles conversion of a given image file to ASCII art file 65 | #[allow(clippy::cast_possible_truncation)] 66 | #[allow(clippy::cast_sign_loss)] 67 | #[allow(clippy::cast_precision_loss)] 68 | pub fn render(input_file_path: &String, output_file_path: &String, scale: &[f32], contrast: &f32) -> Result<(), String> { 69 | // Scale validation 70 | if scale[0] < 0.0 || scale[1] < 0.0 { 71 | return Err(String::from("Scale cannot be negative")); 72 | } 73 | 74 | // Read raw image data from the file 75 | let img = ImageReader::open(input_file_path).map_err(|e| format!("{input_file_path}: {e}"))?; 76 | 77 | // Set up and enable progress indicator 78 | let spinner = ProgressBar::new_spinner(); 79 | spinner.set_style(ProgressStyle::with_template("{spinner:.default} {msg}").map_err(|e| format!("{e}"))?.tick_strings(&[ 80 | "[ ]", 81 | "[= ]", 82 | "[== ]", 83 | "[=== ]", 84 | "[====]", 85 | "[ ===]", 86 | "[ ==]", 87 | "[ =]", 88 | "[ ]", 89 | "[ =]", 90 | "[ ==]", 91 | "[ ===]", 92 | "[====]", 93 | "[=== ]", 94 | "[== ]", 95 | "[= ]", 96 | "[====]" 97 | ]) 98 | ); 99 | spinner.set_message("Decoding"); 100 | spinner.enable_steady_tick(Duration::from_millis(SPINNER_TICK)); 101 | 102 | // Decode the raw image 103 | let mut img_decoded = img.decode().map_err(|e| format!("{input_file_path}: {e}"))?; 104 | 105 | spinner.set_message("Processing"); 106 | 107 | // Image processing 108 | img_decoded = img_decoded 109 | .resize_exact( 110 | (img_decoded.width() as f32 * scale[0]) as u32, 111 | (img_decoded.height() as f32 * scale[1]) as u32, 112 | FilterType::Nearest 113 | ) 114 | .grayscale() 115 | .filter3x3(&[0.0, -1.0, 0.0, -1.0, 5.0, -1.0, 0.0, -1.0, 0.0]) 116 | .adjust_contrast(contrast.to_owned()); 117 | 118 | spinner.set_message("Conversion"); 119 | 120 | // Conversion to ASCII art 121 | let mut ascii_img = convert_to_ascii(&img_decoded); 122 | 123 | // Add metadata 124 | ascii_img.append(&mut format!("Scale: {}, {}\nContrast: {contrast}", scale[0], scale[1]).as_bytes().to_vec()); 125 | 126 | spinner.set_message("Compression"); 127 | 128 | // Compression 129 | ascii_img = compress_to_vec(&ascii_img, 10); 130 | 131 | // Disable the progress indicator 132 | spinner.finish_with_message("Done"); 133 | 134 | // Create/open the output file for writing 135 | let mut output_file = File::create(output_file_path).map_err(|e| format!("{output_file_path}: {e}"))?; 136 | 137 | // Write data to the output file 138 | output_file.write_all(&ascii_img).map_err(|e| format!("{output_file_path}: {e}"))?; 139 | 140 | Ok(()) 141 | } 142 | 143 | fn convert_to_ascii(image: &DynamicImage) -> Vec { 144 | let mut ascii_image = Vec::new(); 145 | 146 | for y in 0..image.height() { 147 | for x in 0..image.width() { 148 | // Map ASCII grayscale characters to pixel values 149 | ascii_image.push(GRAYSCALE 150 | .as_bytes() 151 | [ 152 | usize::from(image.get_pixel(x, y).channels()[0]) / 4 153 | ] 154 | ); 155 | } 156 | 157 | // Add newline at the end 158 | ascii_image.push(b'\n'); 159 | } 160 | 161 | ascii_image 162 | } 163 | 164 | /// Reads the contents of a given ASCII art file and prints it to the standard output 165 | pub fn open(input_file_path: &String) -> Result<(), String> { 166 | // Open the file containing compressed ASCII art 167 | let mut input_file = File::open(input_file_path).map_err(|e| format!("{input_file_path}: {e}"))?; 168 | 169 | let mut contents = Vec::new(); 170 | 171 | // Read the contents of the file 172 | input_file.read_to_end(&mut contents).map_err(|e| format!("{input_file_path}: {e}"))?; 173 | 174 | // Decompress read data 175 | contents = decompress_to_vec(&contents).map_err(|e| format!("{e}"))?; 176 | 177 | // Decode the data as string 178 | let contents_str = str::from_utf8(&contents).map_err(|e| format!("{e}"))?; 179 | 180 | // Print the string to the standard output 181 | println!("{contents_str}"); 182 | 183 | Ok(()) 184 | } 185 | 186 | /// Prints given error message to the standard error with application name and then exits the application with specified error code 187 | pub fn handle_error(error: &str, code: i32) { 188 | eprintln!("{APP_NAME}: {error}"); 189 | process::exit(code); 190 | } 191 | 192 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | use rustii::{Cli, Commands, handle_error, open, render}; 4 | 5 | fn main() { 6 | let cli = Cli::parse(); 7 | 8 | match cli.get_command() { 9 | Commands::Render { input_file_path, output, scale, contrast } => { 10 | if let Err(e) = render(input_file_path, output, scale, contrast) { 11 | handle_error(&e, 1); 12 | } 13 | }, 14 | 15 | Commands::Open { input_file_path } => { 16 | if let Err(e) = open(input_file_path) { 17 | handle_error(&e, 2); 18 | } 19 | } 20 | }; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /tests/ascii.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ndr3www/rustii/c7d968065e3251ea865a00d71d6f7c1523632cc4/tests/ascii.txt -------------------------------------------------------------------------------- /tests/image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ndr3www/rustii/c7d968065e3251ea865a00d71d6f7c1523632cc4/tests/image.jpg -------------------------------------------------------------------------------- /tests/integration.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | use rustii::*; 4 | 5 | #[test] 6 | fn case_render() { 7 | let cli = Cli::parse_from([APP_NAME, "render", "tests/image.jpg", "-o", "tests/ascii.txt", "-s", "0.65", "0.25", "-c", "20"]); 8 | 9 | match cli.get_command() { 10 | Commands::Render { input_file_path, output, scale, contrast } => { 11 | assert_eq!(render(input_file_path, output, scale, contrast), Ok(())); 12 | }, 13 | _ => () 14 | }; 15 | } 16 | 17 | #[test] 18 | fn case_open() { 19 | let cli = Cli::parse_from([APP_NAME, "open", "tests/ascii.txt"]); 20 | 21 | match cli.get_command() { 22 | Commands::Open { input_file_path } => { 23 | assert_eq!(open(input_file_path), Ok(())); 24 | }, 25 | _ => () 26 | }; 27 | } 28 | 29 | --------------------------------------------------------------------------------