├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md ├── _readme ├── photo.jpg ├── rust.jpg └── starry-night.jpg ├── images ├── girl-with-a-pearl-earring.jpg ├── ophelia.jpg └── starry-night.jpg ├── rust-toolchain.toml ├── shell.nix └── src └── main.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "adler2" 7 | version = "2.0.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 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.18" 20 | source = "registry+https://github.com/rust-lang/crates.io-index" 21 | checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" 22 | dependencies = [ 23 | "anstyle", 24 | "anstyle-parse", 25 | "anstyle-query", 26 | "anstyle-wincon", 27 | "colorchoice", 28 | "is_terminal_polyfill", 29 | "utf8parse", 30 | ] 31 | 32 | [[package]] 33 | name = "anstyle" 34 | version = "1.0.10" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" 37 | 38 | [[package]] 39 | name = "anstyle-parse" 40 | version = "0.2.6" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" 43 | dependencies = [ 44 | "utf8parse", 45 | ] 46 | 47 | [[package]] 48 | name = "anstyle-query" 49 | version = "1.1.2" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" 52 | dependencies = [ 53 | "windows-sys", 54 | ] 55 | 56 | [[package]] 57 | name = "anstyle-wincon" 58 | version = "3.0.6" 59 | source = "registry+https://github.com/rust-lang/crates.io-index" 60 | checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" 61 | dependencies = [ 62 | "anstyle", 63 | "windows-sys", 64 | ] 65 | 66 | [[package]] 67 | name = "anyhow" 68 | version = "1.0.95" 69 | source = "registry+https://github.com/rust-lang/crates.io-index" 70 | checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" 71 | 72 | [[package]] 73 | name = "arbitrary" 74 | version = "1.4.1" 75 | source = "registry+https://github.com/rust-lang/crates.io-index" 76 | checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" 77 | 78 | [[package]] 79 | name = "arg_enum_proc_macro" 80 | version = "0.3.4" 81 | source = "registry+https://github.com/rust-lang/crates.io-index" 82 | checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" 83 | dependencies = [ 84 | "proc-macro2", 85 | "quote", 86 | "syn", 87 | ] 88 | 89 | [[package]] 90 | name = "arrayvec" 91 | version = "0.7.6" 92 | source = "registry+https://github.com/rust-lang/crates.io-index" 93 | checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" 94 | 95 | [[package]] 96 | name = "autocfg" 97 | version = "1.4.0" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 100 | 101 | [[package]] 102 | name = "av1-grain" 103 | version = "0.2.3" 104 | source = "registry+https://github.com/rust-lang/crates.io-index" 105 | checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" 106 | dependencies = [ 107 | "anyhow", 108 | "arrayvec", 109 | "log", 110 | "nom", 111 | "num-rational", 112 | "v_frame", 113 | ] 114 | 115 | [[package]] 116 | name = "avif-serialize" 117 | version = "0.8.2" 118 | source = "registry+https://github.com/rust-lang/crates.io-index" 119 | checksum = "e335041290c43101ca215eed6f43ec437eb5a42125573f600fc3fa42b9bddd62" 120 | dependencies = [ 121 | "arrayvec", 122 | ] 123 | 124 | [[package]] 125 | name = "bit_field" 126 | version = "0.10.2" 127 | source = "registry+https://github.com/rust-lang/crates.io-index" 128 | checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" 129 | 130 | [[package]] 131 | name = "bitflags" 132 | version = "1.3.2" 133 | source = "registry+https://github.com/rust-lang/crates.io-index" 134 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 135 | 136 | [[package]] 137 | name = "bitflags" 138 | version = "2.6.0" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 141 | 142 | [[package]] 143 | name = "bitstream-io" 144 | version = "2.6.0" 145 | source = "registry+https://github.com/rust-lang/crates.io-index" 146 | checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2" 147 | 148 | [[package]] 149 | name = "bresenham" 150 | version = "0.1.1" 151 | source = "registry+https://github.com/rust-lang/crates.io-index" 152 | checksum = "bfc1116225f66d2ea341a26503f83a6b1205070a6f7199ce1f1550ead91f6fd7" 153 | 154 | [[package]] 155 | name = "built" 156 | version = "0.7.5" 157 | source = "registry+https://github.com/rust-lang/crates.io-index" 158 | checksum = "c360505aed52b7ec96a3636c3f039d99103c37d1d9b4f7a8c743d3ea9ffcd03b" 159 | 160 | [[package]] 161 | name = "bumpalo" 162 | version = "3.16.0" 163 | source = "registry+https://github.com/rust-lang/crates.io-index" 164 | checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" 165 | 166 | [[package]] 167 | name = "bytemuck" 168 | version = "1.21.0" 169 | source = "registry+https://github.com/rust-lang/crates.io-index" 170 | checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" 171 | 172 | [[package]] 173 | name = "byteorder" 174 | version = "1.5.0" 175 | source = "registry+https://github.com/rust-lang/crates.io-index" 176 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 177 | 178 | [[package]] 179 | name = "byteorder-lite" 180 | version = "0.1.0" 181 | source = "registry+https://github.com/rust-lang/crates.io-index" 182 | checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" 183 | 184 | [[package]] 185 | name = "cc" 186 | version = "1.2.7" 187 | source = "registry+https://github.com/rust-lang/crates.io-index" 188 | checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7" 189 | dependencies = [ 190 | "jobserver", 191 | "libc", 192 | "shlex", 193 | ] 194 | 195 | [[package]] 196 | name = "cfg-expr" 197 | version = "0.15.8" 198 | source = "registry+https://github.com/rust-lang/crates.io-index" 199 | checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" 200 | dependencies = [ 201 | "smallvec", 202 | "target-lexicon", 203 | ] 204 | 205 | [[package]] 206 | name = "cfg-if" 207 | version = "1.0.0" 208 | source = "registry+https://github.com/rust-lang/crates.io-index" 209 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 210 | 211 | [[package]] 212 | name = "clap" 213 | version = "4.5.24" 214 | source = "registry+https://github.com/rust-lang/crates.io-index" 215 | checksum = "9560b07a799281c7e0958b9296854d6fafd4c5f31444a7e5bb1ad6dde5ccf1bd" 216 | dependencies = [ 217 | "clap_builder", 218 | "clap_derive", 219 | ] 220 | 221 | [[package]] 222 | name = "clap_builder" 223 | version = "4.5.24" 224 | source = "registry+https://github.com/rust-lang/crates.io-index" 225 | checksum = "874e0dd3eb68bf99058751ac9712f622e61e6f393a94f7128fa26e3f02f5c7cd" 226 | dependencies = [ 227 | "anstream", 228 | "anstyle", 229 | "clap_lex", 230 | "strsim", 231 | ] 232 | 233 | [[package]] 234 | name = "clap_derive" 235 | version = "4.5.24" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c" 238 | dependencies = [ 239 | "heck", 240 | "proc-macro2", 241 | "quote", 242 | "syn", 243 | ] 244 | 245 | [[package]] 246 | name = "clap_lex" 247 | version = "0.7.4" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" 250 | 251 | [[package]] 252 | name = "color_quant" 253 | version = "1.1.0" 254 | source = "registry+https://github.com/rust-lang/crates.io-index" 255 | checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" 256 | 257 | [[package]] 258 | name = "colorchoice" 259 | version = "1.0.3" 260 | source = "registry+https://github.com/rust-lang/crates.io-index" 261 | checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" 262 | 263 | [[package]] 264 | name = "crc32fast" 265 | version = "1.4.2" 266 | source = "registry+https://github.com/rust-lang/crates.io-index" 267 | checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" 268 | dependencies = [ 269 | "cfg-if", 270 | ] 271 | 272 | [[package]] 273 | name = "crossbeam-deque" 274 | version = "0.8.6" 275 | source = "registry+https://github.com/rust-lang/crates.io-index" 276 | checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" 277 | dependencies = [ 278 | "crossbeam-epoch", 279 | "crossbeam-utils", 280 | ] 281 | 282 | [[package]] 283 | name = "crossbeam-epoch" 284 | version = "0.9.18" 285 | source = "registry+https://github.com/rust-lang/crates.io-index" 286 | checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" 287 | dependencies = [ 288 | "crossbeam-utils", 289 | ] 290 | 291 | [[package]] 292 | name = "crossbeam-utils" 293 | version = "0.8.21" 294 | source = "registry+https://github.com/rust-lang/crates.io-index" 295 | checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" 296 | 297 | [[package]] 298 | name = "crunchy" 299 | version = "0.2.2" 300 | source = "registry+https://github.com/rust-lang/crates.io-index" 301 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 302 | 303 | [[package]] 304 | name = "dlib" 305 | version = "0.5.2" 306 | source = "registry+https://github.com/rust-lang/crates.io-index" 307 | checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" 308 | dependencies = [ 309 | "libloading", 310 | ] 311 | 312 | [[package]] 313 | name = "downcast-rs" 314 | version = "1.2.1" 315 | source = "registry+https://github.com/rust-lang/crates.io-index" 316 | checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" 317 | 318 | [[package]] 319 | name = "either" 320 | version = "1.13.0" 321 | source = "registry+https://github.com/rust-lang/crates.io-index" 322 | checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" 323 | 324 | [[package]] 325 | name = "equivalent" 326 | version = "1.0.1" 327 | source = "registry+https://github.com/rust-lang/crates.io-index" 328 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 329 | 330 | [[package]] 331 | name = "errno" 332 | version = "0.3.10" 333 | source = "registry+https://github.com/rust-lang/crates.io-index" 334 | checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" 335 | dependencies = [ 336 | "libc", 337 | "windows-sys", 338 | ] 339 | 340 | [[package]] 341 | name = "exr" 342 | version = "1.73.0" 343 | source = "registry+https://github.com/rust-lang/crates.io-index" 344 | checksum = "f83197f59927b46c04a183a619b7c29df34e63e63c7869320862268c0ef687e0" 345 | dependencies = [ 346 | "bit_field", 347 | "half", 348 | "lebe", 349 | "miniz_oxide", 350 | "rayon-core", 351 | "smallvec", 352 | "zune-inflate", 353 | ] 354 | 355 | [[package]] 356 | name = "fastrand" 357 | version = "2.3.0" 358 | source = "registry+https://github.com/rust-lang/crates.io-index" 359 | checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" 360 | 361 | [[package]] 362 | name = "fdeflate" 363 | version = "0.3.7" 364 | source = "registry+https://github.com/rust-lang/crates.io-index" 365 | checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" 366 | dependencies = [ 367 | "simd-adler32", 368 | ] 369 | 370 | [[package]] 371 | name = "flate2" 372 | version = "1.0.35" 373 | source = "registry+https://github.com/rust-lang/crates.io-index" 374 | checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" 375 | dependencies = [ 376 | "crc32fast", 377 | "miniz_oxide", 378 | ] 379 | 380 | [[package]] 381 | name = "futures" 382 | version = "0.3.31" 383 | source = "registry+https://github.com/rust-lang/crates.io-index" 384 | checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" 385 | dependencies = [ 386 | "futures-channel", 387 | "futures-core", 388 | "futures-executor", 389 | "futures-io", 390 | "futures-sink", 391 | "futures-task", 392 | "futures-util", 393 | ] 394 | 395 | [[package]] 396 | name = "futures-channel" 397 | version = "0.3.31" 398 | source = "registry+https://github.com/rust-lang/crates.io-index" 399 | checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 400 | dependencies = [ 401 | "futures-core", 402 | "futures-sink", 403 | ] 404 | 405 | [[package]] 406 | name = "futures-core" 407 | version = "0.3.31" 408 | source = "registry+https://github.com/rust-lang/crates.io-index" 409 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 410 | 411 | [[package]] 412 | name = "futures-executor" 413 | version = "0.3.31" 414 | source = "registry+https://github.com/rust-lang/crates.io-index" 415 | checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" 416 | dependencies = [ 417 | "futures-core", 418 | "futures-task", 419 | "futures-util", 420 | ] 421 | 422 | [[package]] 423 | name = "futures-io" 424 | version = "0.3.31" 425 | source = "registry+https://github.com/rust-lang/crates.io-index" 426 | checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" 427 | 428 | [[package]] 429 | name = "futures-macro" 430 | version = "0.3.31" 431 | source = "registry+https://github.com/rust-lang/crates.io-index" 432 | checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" 433 | dependencies = [ 434 | "proc-macro2", 435 | "quote", 436 | "syn", 437 | ] 438 | 439 | [[package]] 440 | name = "futures-sink" 441 | version = "0.3.31" 442 | source = "registry+https://github.com/rust-lang/crates.io-index" 443 | checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 444 | 445 | [[package]] 446 | name = "futures-task" 447 | version = "0.3.31" 448 | source = "registry+https://github.com/rust-lang/crates.io-index" 449 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 450 | 451 | [[package]] 452 | name = "futures-util" 453 | version = "0.3.31" 454 | source = "registry+https://github.com/rust-lang/crates.io-index" 455 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 456 | dependencies = [ 457 | "futures-channel", 458 | "futures-core", 459 | "futures-io", 460 | "futures-macro", 461 | "futures-sink", 462 | "futures-task", 463 | "memchr", 464 | "pin-project-lite", 465 | "pin-utils", 466 | "slab", 467 | ] 468 | 469 | [[package]] 470 | name = "getrandom" 471 | version = "0.2.15" 472 | source = "registry+https://github.com/rust-lang/crates.io-index" 473 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 474 | dependencies = [ 475 | "cfg-if", 476 | "libc", 477 | "wasi", 478 | ] 479 | 480 | [[package]] 481 | name = "gif" 482 | version = "0.13.1" 483 | source = "registry+https://github.com/rust-lang/crates.io-index" 484 | checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" 485 | dependencies = [ 486 | "color_quant", 487 | "weezl", 488 | ] 489 | 490 | [[package]] 491 | name = "half" 492 | version = "2.4.1" 493 | source = "registry+https://github.com/rust-lang/crates.io-index" 494 | checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" 495 | dependencies = [ 496 | "cfg-if", 497 | "crunchy", 498 | ] 499 | 500 | [[package]] 501 | name = "hashbrown" 502 | version = "0.15.2" 503 | source = "registry+https://github.com/rust-lang/crates.io-index" 504 | checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" 505 | 506 | [[package]] 507 | name = "heck" 508 | version = "0.5.0" 509 | source = "registry+https://github.com/rust-lang/crates.io-index" 510 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 511 | 512 | [[package]] 513 | name = "image" 514 | version = "0.25.5" 515 | source = "registry+https://github.com/rust-lang/crates.io-index" 516 | checksum = "cd6f44aed642f18953a158afeb30206f4d50da59fbc66ecb53c66488de73563b" 517 | dependencies = [ 518 | "bytemuck", 519 | "byteorder-lite", 520 | "color_quant", 521 | "exr", 522 | "gif", 523 | "image-webp", 524 | "num-traits", 525 | "png", 526 | "qoi", 527 | "ravif", 528 | "rayon", 529 | "rgb", 530 | "tiff", 531 | "zune-core", 532 | "zune-jpeg", 533 | ] 534 | 535 | [[package]] 536 | name = "image-webp" 537 | version = "0.2.0" 538 | source = "registry+https://github.com/rust-lang/crates.io-index" 539 | checksum = "e031e8e3d94711a9ccb5d6ea357439ef3dcbed361798bd4071dc4d9793fbe22f" 540 | dependencies = [ 541 | "byteorder-lite", 542 | "quick-error", 543 | ] 544 | 545 | [[package]] 546 | name = "imgref" 547 | version = "1.11.0" 548 | source = "registry+https://github.com/rust-lang/crates.io-index" 549 | checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408" 550 | 551 | [[package]] 552 | name = "indexmap" 553 | version = "2.7.0" 554 | source = "registry+https://github.com/rust-lang/crates.io-index" 555 | checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" 556 | dependencies = [ 557 | "equivalent", 558 | "hashbrown", 559 | ] 560 | 561 | [[package]] 562 | name = "instant" 563 | version = "0.1.13" 564 | source = "registry+https://github.com/rust-lang/crates.io-index" 565 | checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" 566 | dependencies = [ 567 | "cfg-if", 568 | "js-sys", 569 | "wasm-bindgen", 570 | "web-sys", 571 | ] 572 | 573 | [[package]] 574 | name = "interpolate_name" 575 | version = "0.2.4" 576 | source = "registry+https://github.com/rust-lang/crates.io-index" 577 | checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" 578 | dependencies = [ 579 | "proc-macro2", 580 | "quote", 581 | "syn", 582 | ] 583 | 584 | [[package]] 585 | name = "is_terminal_polyfill" 586 | version = "1.70.1" 587 | source = "registry+https://github.com/rust-lang/crates.io-index" 588 | checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 589 | 590 | [[package]] 591 | name = "itertools" 592 | version = "0.12.1" 593 | source = "registry+https://github.com/rust-lang/crates.io-index" 594 | checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" 595 | dependencies = [ 596 | "either", 597 | ] 598 | 599 | [[package]] 600 | name = "jobserver" 601 | version = "0.1.32" 602 | source = "registry+https://github.com/rust-lang/crates.io-index" 603 | checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" 604 | dependencies = [ 605 | "libc", 606 | ] 607 | 608 | [[package]] 609 | name = "jpeg-decoder" 610 | version = "0.3.1" 611 | source = "registry+https://github.com/rust-lang/crates.io-index" 612 | checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" 613 | 614 | [[package]] 615 | name = "js-sys" 616 | version = "0.3.76" 617 | source = "registry+https://github.com/rust-lang/crates.io-index" 618 | checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" 619 | dependencies = [ 620 | "once_cell", 621 | "wasm-bindgen", 622 | ] 623 | 624 | [[package]] 625 | name = "lazy_static" 626 | version = "1.5.0" 627 | source = "registry+https://github.com/rust-lang/crates.io-index" 628 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 629 | 630 | [[package]] 631 | name = "lebe" 632 | version = "0.5.2" 633 | source = "registry+https://github.com/rust-lang/crates.io-index" 634 | checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" 635 | 636 | [[package]] 637 | name = "libc" 638 | version = "0.2.169" 639 | source = "registry+https://github.com/rust-lang/crates.io-index" 640 | checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" 641 | 642 | [[package]] 643 | name = "libfuzzer-sys" 644 | version = "0.4.8" 645 | source = "registry+https://github.com/rust-lang/crates.io-index" 646 | checksum = "9b9569d2f74e257076d8c6bfa73fb505b46b851e51ddaecc825944aa3bed17fa" 647 | dependencies = [ 648 | "arbitrary", 649 | "cc", 650 | ] 651 | 652 | [[package]] 653 | name = "libloading" 654 | version = "0.8.6" 655 | source = "registry+https://github.com/rust-lang/crates.io-index" 656 | checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" 657 | dependencies = [ 658 | "cfg-if", 659 | "windows-targets", 660 | ] 661 | 662 | [[package]] 663 | name = "libredox" 664 | version = "0.1.3" 665 | source = "registry+https://github.com/rust-lang/crates.io-index" 666 | checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" 667 | dependencies = [ 668 | "bitflags 2.6.0", 669 | "libc", 670 | "redox_syscall", 671 | ] 672 | 673 | [[package]] 674 | name = "linez" 675 | version = "0.1.0" 676 | dependencies = [ 677 | "bresenham", 678 | "clap", 679 | "image", 680 | "minifb", 681 | "rand", 682 | ] 683 | 684 | [[package]] 685 | name = "linux-raw-sys" 686 | version = "0.4.15" 687 | source = "registry+https://github.com/rust-lang/crates.io-index" 688 | checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" 689 | 690 | [[package]] 691 | name = "log" 692 | version = "0.4.22" 693 | source = "registry+https://github.com/rust-lang/crates.io-index" 694 | checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" 695 | 696 | [[package]] 697 | name = "loop9" 698 | version = "0.1.5" 699 | source = "registry+https://github.com/rust-lang/crates.io-index" 700 | checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" 701 | dependencies = [ 702 | "imgref", 703 | ] 704 | 705 | [[package]] 706 | name = "maybe-rayon" 707 | version = "0.1.1" 708 | source = "registry+https://github.com/rust-lang/crates.io-index" 709 | checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" 710 | dependencies = [ 711 | "cfg-if", 712 | "rayon", 713 | ] 714 | 715 | [[package]] 716 | name = "memchr" 717 | version = "2.7.4" 718 | source = "registry+https://github.com/rust-lang/crates.io-index" 719 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 720 | 721 | [[package]] 722 | name = "memoffset" 723 | version = "0.6.5" 724 | source = "registry+https://github.com/rust-lang/crates.io-index" 725 | checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" 726 | dependencies = [ 727 | "autocfg", 728 | ] 729 | 730 | [[package]] 731 | name = "minifb" 732 | version = "0.27.0" 733 | source = "registry+https://github.com/rust-lang/crates.io-index" 734 | checksum = "b0c470a74618b43cd182c21b3dc1e6123501249f3bad9a0085e95d1304ca2478" 735 | dependencies = [ 736 | "cc", 737 | "dlib", 738 | "futures", 739 | "instant", 740 | "js-sys", 741 | "lazy_static", 742 | "libc", 743 | "orbclient", 744 | "raw-window-handle", 745 | "serde", 746 | "serde_derive", 747 | "tempfile", 748 | "wasm-bindgen-futures", 749 | "wayland-client", 750 | "wayland-cursor", 751 | "wayland-protocols", 752 | "winapi", 753 | "x11-dl", 754 | ] 755 | 756 | [[package]] 757 | name = "minimal-lexical" 758 | version = "0.2.1" 759 | source = "registry+https://github.com/rust-lang/crates.io-index" 760 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 761 | 762 | [[package]] 763 | name = "miniz_oxide" 764 | version = "0.8.2" 765 | source = "registry+https://github.com/rust-lang/crates.io-index" 766 | checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" 767 | dependencies = [ 768 | "adler2", 769 | "simd-adler32", 770 | ] 771 | 772 | [[package]] 773 | name = "new_debug_unreachable" 774 | version = "1.0.6" 775 | source = "registry+https://github.com/rust-lang/crates.io-index" 776 | checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" 777 | 778 | [[package]] 779 | name = "nix" 780 | version = "0.24.3" 781 | source = "registry+https://github.com/rust-lang/crates.io-index" 782 | checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" 783 | dependencies = [ 784 | "bitflags 1.3.2", 785 | "cfg-if", 786 | "libc", 787 | "memoffset", 788 | ] 789 | 790 | [[package]] 791 | name = "nom" 792 | version = "7.1.3" 793 | source = "registry+https://github.com/rust-lang/crates.io-index" 794 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 795 | dependencies = [ 796 | "memchr", 797 | "minimal-lexical", 798 | ] 799 | 800 | [[package]] 801 | name = "noop_proc_macro" 802 | version = "0.3.0" 803 | source = "registry+https://github.com/rust-lang/crates.io-index" 804 | checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" 805 | 806 | [[package]] 807 | name = "num-bigint" 808 | version = "0.4.6" 809 | source = "registry+https://github.com/rust-lang/crates.io-index" 810 | checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" 811 | dependencies = [ 812 | "num-integer", 813 | "num-traits", 814 | ] 815 | 816 | [[package]] 817 | name = "num-derive" 818 | version = "0.4.2" 819 | source = "registry+https://github.com/rust-lang/crates.io-index" 820 | checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" 821 | dependencies = [ 822 | "proc-macro2", 823 | "quote", 824 | "syn", 825 | ] 826 | 827 | [[package]] 828 | name = "num-integer" 829 | version = "0.1.46" 830 | source = "registry+https://github.com/rust-lang/crates.io-index" 831 | checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" 832 | dependencies = [ 833 | "num-traits", 834 | ] 835 | 836 | [[package]] 837 | name = "num-rational" 838 | version = "0.4.2" 839 | source = "registry+https://github.com/rust-lang/crates.io-index" 840 | checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" 841 | dependencies = [ 842 | "num-bigint", 843 | "num-integer", 844 | "num-traits", 845 | ] 846 | 847 | [[package]] 848 | name = "num-traits" 849 | version = "0.2.19" 850 | source = "registry+https://github.com/rust-lang/crates.io-index" 851 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 852 | dependencies = [ 853 | "autocfg", 854 | ] 855 | 856 | [[package]] 857 | name = "once_cell" 858 | version = "1.20.2" 859 | source = "registry+https://github.com/rust-lang/crates.io-index" 860 | checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" 861 | 862 | [[package]] 863 | name = "orbclient" 864 | version = "0.3.48" 865 | source = "registry+https://github.com/rust-lang/crates.io-index" 866 | checksum = "ba0b26cec2e24f08ed8bb31519a9333140a6599b867dac464bb150bdb796fd43" 867 | dependencies = [ 868 | "libc", 869 | "libredox", 870 | "sdl2", 871 | "sdl2-sys", 872 | ] 873 | 874 | [[package]] 875 | name = "paste" 876 | version = "1.0.15" 877 | source = "registry+https://github.com/rust-lang/crates.io-index" 878 | checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" 879 | 880 | [[package]] 881 | name = "pin-project-lite" 882 | version = "0.2.16" 883 | source = "registry+https://github.com/rust-lang/crates.io-index" 884 | checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 885 | 886 | [[package]] 887 | name = "pin-utils" 888 | version = "0.1.0" 889 | source = "registry+https://github.com/rust-lang/crates.io-index" 890 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 891 | 892 | [[package]] 893 | name = "pkg-config" 894 | version = "0.3.31" 895 | source = "registry+https://github.com/rust-lang/crates.io-index" 896 | checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" 897 | 898 | [[package]] 899 | name = "png" 900 | version = "0.17.16" 901 | source = "registry+https://github.com/rust-lang/crates.io-index" 902 | checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" 903 | dependencies = [ 904 | "bitflags 1.3.2", 905 | "crc32fast", 906 | "fdeflate", 907 | "flate2", 908 | "miniz_oxide", 909 | ] 910 | 911 | [[package]] 912 | name = "ppv-lite86" 913 | version = "0.2.20" 914 | source = "registry+https://github.com/rust-lang/crates.io-index" 915 | checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" 916 | dependencies = [ 917 | "zerocopy", 918 | ] 919 | 920 | [[package]] 921 | name = "proc-macro2" 922 | version = "1.0.92" 923 | source = "registry+https://github.com/rust-lang/crates.io-index" 924 | checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" 925 | dependencies = [ 926 | "unicode-ident", 927 | ] 928 | 929 | [[package]] 930 | name = "profiling" 931 | version = "1.0.16" 932 | source = "registry+https://github.com/rust-lang/crates.io-index" 933 | checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" 934 | dependencies = [ 935 | "profiling-procmacros", 936 | ] 937 | 938 | [[package]] 939 | name = "profiling-procmacros" 940 | version = "1.0.16" 941 | source = "registry+https://github.com/rust-lang/crates.io-index" 942 | checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30" 943 | dependencies = [ 944 | "quote", 945 | "syn", 946 | ] 947 | 948 | [[package]] 949 | name = "qoi" 950 | version = "0.4.1" 951 | source = "registry+https://github.com/rust-lang/crates.io-index" 952 | checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" 953 | dependencies = [ 954 | "bytemuck", 955 | ] 956 | 957 | [[package]] 958 | name = "quick-error" 959 | version = "2.0.1" 960 | source = "registry+https://github.com/rust-lang/crates.io-index" 961 | checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" 962 | 963 | [[package]] 964 | name = "quote" 965 | version = "1.0.38" 966 | source = "registry+https://github.com/rust-lang/crates.io-index" 967 | checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" 968 | dependencies = [ 969 | "proc-macro2", 970 | ] 971 | 972 | [[package]] 973 | name = "rand" 974 | version = "0.8.5" 975 | source = "registry+https://github.com/rust-lang/crates.io-index" 976 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 977 | dependencies = [ 978 | "libc", 979 | "rand_chacha", 980 | "rand_core", 981 | ] 982 | 983 | [[package]] 984 | name = "rand_chacha" 985 | version = "0.3.1" 986 | source = "registry+https://github.com/rust-lang/crates.io-index" 987 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 988 | dependencies = [ 989 | "ppv-lite86", 990 | "rand_core", 991 | ] 992 | 993 | [[package]] 994 | name = "rand_core" 995 | version = "0.6.4" 996 | source = "registry+https://github.com/rust-lang/crates.io-index" 997 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 998 | dependencies = [ 999 | "getrandom", 1000 | ] 1001 | 1002 | [[package]] 1003 | name = "rav1e" 1004 | version = "0.7.1" 1005 | source = "registry+https://github.com/rust-lang/crates.io-index" 1006 | checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" 1007 | dependencies = [ 1008 | "arbitrary", 1009 | "arg_enum_proc_macro", 1010 | "arrayvec", 1011 | "av1-grain", 1012 | "bitstream-io", 1013 | "built", 1014 | "cfg-if", 1015 | "interpolate_name", 1016 | "itertools", 1017 | "libc", 1018 | "libfuzzer-sys", 1019 | "log", 1020 | "maybe-rayon", 1021 | "new_debug_unreachable", 1022 | "noop_proc_macro", 1023 | "num-derive", 1024 | "num-traits", 1025 | "once_cell", 1026 | "paste", 1027 | "profiling", 1028 | "rand", 1029 | "rand_chacha", 1030 | "simd_helpers", 1031 | "system-deps", 1032 | "thiserror", 1033 | "v_frame", 1034 | "wasm-bindgen", 1035 | ] 1036 | 1037 | [[package]] 1038 | name = "ravif" 1039 | version = "0.11.11" 1040 | source = "registry+https://github.com/rust-lang/crates.io-index" 1041 | checksum = "2413fd96bd0ea5cdeeb37eaf446a22e6ed7b981d792828721e74ded1980a45c6" 1042 | dependencies = [ 1043 | "avif-serialize", 1044 | "imgref", 1045 | "loop9", 1046 | "quick-error", 1047 | "rav1e", 1048 | "rayon", 1049 | "rgb", 1050 | ] 1051 | 1052 | [[package]] 1053 | name = "raw-window-handle" 1054 | version = "0.6.2" 1055 | source = "registry+https://github.com/rust-lang/crates.io-index" 1056 | checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" 1057 | 1058 | [[package]] 1059 | name = "rayon" 1060 | version = "1.10.0" 1061 | source = "registry+https://github.com/rust-lang/crates.io-index" 1062 | checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" 1063 | dependencies = [ 1064 | "either", 1065 | "rayon-core", 1066 | ] 1067 | 1068 | [[package]] 1069 | name = "rayon-core" 1070 | version = "1.12.1" 1071 | source = "registry+https://github.com/rust-lang/crates.io-index" 1072 | checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" 1073 | dependencies = [ 1074 | "crossbeam-deque", 1075 | "crossbeam-utils", 1076 | ] 1077 | 1078 | [[package]] 1079 | name = "redox_syscall" 1080 | version = "0.5.8" 1081 | source = "registry+https://github.com/rust-lang/crates.io-index" 1082 | checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" 1083 | dependencies = [ 1084 | "bitflags 2.6.0", 1085 | ] 1086 | 1087 | [[package]] 1088 | name = "rgb" 1089 | version = "0.8.50" 1090 | source = "registry+https://github.com/rust-lang/crates.io-index" 1091 | checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" 1092 | 1093 | [[package]] 1094 | name = "rustix" 1095 | version = "0.38.43" 1096 | source = "registry+https://github.com/rust-lang/crates.io-index" 1097 | checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" 1098 | dependencies = [ 1099 | "bitflags 2.6.0", 1100 | "errno", 1101 | "libc", 1102 | "linux-raw-sys", 1103 | "windows-sys", 1104 | ] 1105 | 1106 | [[package]] 1107 | name = "scoped-tls" 1108 | version = "1.0.1" 1109 | source = "registry+https://github.com/rust-lang/crates.io-index" 1110 | checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" 1111 | 1112 | [[package]] 1113 | name = "sdl2" 1114 | version = "0.35.2" 1115 | source = "registry+https://github.com/rust-lang/crates.io-index" 1116 | checksum = "f7959277b623f1fb9e04aea73686c3ca52f01b2145f8ea16f4ff30d8b7623b1a" 1117 | dependencies = [ 1118 | "bitflags 1.3.2", 1119 | "lazy_static", 1120 | "libc", 1121 | "sdl2-sys", 1122 | ] 1123 | 1124 | [[package]] 1125 | name = "sdl2-sys" 1126 | version = "0.35.2" 1127 | source = "registry+https://github.com/rust-lang/crates.io-index" 1128 | checksum = "e3586be2cf6c0a8099a79a12b4084357aa9b3e0b0d7980e3b67aaf7a9d55f9f0" 1129 | dependencies = [ 1130 | "cfg-if", 1131 | "libc", 1132 | "version-compare 0.1.1", 1133 | ] 1134 | 1135 | [[package]] 1136 | name = "serde" 1137 | version = "1.0.217" 1138 | source = "registry+https://github.com/rust-lang/crates.io-index" 1139 | checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" 1140 | dependencies = [ 1141 | "serde_derive", 1142 | ] 1143 | 1144 | [[package]] 1145 | name = "serde_derive" 1146 | version = "1.0.217" 1147 | source = "registry+https://github.com/rust-lang/crates.io-index" 1148 | checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" 1149 | dependencies = [ 1150 | "proc-macro2", 1151 | "quote", 1152 | "syn", 1153 | ] 1154 | 1155 | [[package]] 1156 | name = "serde_spanned" 1157 | version = "0.6.8" 1158 | source = "registry+https://github.com/rust-lang/crates.io-index" 1159 | checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" 1160 | dependencies = [ 1161 | "serde", 1162 | ] 1163 | 1164 | [[package]] 1165 | name = "shlex" 1166 | version = "1.3.0" 1167 | source = "registry+https://github.com/rust-lang/crates.io-index" 1168 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 1169 | 1170 | [[package]] 1171 | name = "simd-adler32" 1172 | version = "0.3.7" 1173 | source = "registry+https://github.com/rust-lang/crates.io-index" 1174 | checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" 1175 | 1176 | [[package]] 1177 | name = "simd_helpers" 1178 | version = "0.1.0" 1179 | source = "registry+https://github.com/rust-lang/crates.io-index" 1180 | checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" 1181 | dependencies = [ 1182 | "quote", 1183 | ] 1184 | 1185 | [[package]] 1186 | name = "slab" 1187 | version = "0.4.9" 1188 | source = "registry+https://github.com/rust-lang/crates.io-index" 1189 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1190 | dependencies = [ 1191 | "autocfg", 1192 | ] 1193 | 1194 | [[package]] 1195 | name = "smallvec" 1196 | version = "1.13.2" 1197 | source = "registry+https://github.com/rust-lang/crates.io-index" 1198 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 1199 | 1200 | [[package]] 1201 | name = "strsim" 1202 | version = "0.11.1" 1203 | source = "registry+https://github.com/rust-lang/crates.io-index" 1204 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1205 | 1206 | [[package]] 1207 | name = "syn" 1208 | version = "2.0.95" 1209 | source = "registry+https://github.com/rust-lang/crates.io-index" 1210 | checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a" 1211 | dependencies = [ 1212 | "proc-macro2", 1213 | "quote", 1214 | "unicode-ident", 1215 | ] 1216 | 1217 | [[package]] 1218 | name = "system-deps" 1219 | version = "6.2.2" 1220 | source = "registry+https://github.com/rust-lang/crates.io-index" 1221 | checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" 1222 | dependencies = [ 1223 | "cfg-expr", 1224 | "heck", 1225 | "pkg-config", 1226 | "toml", 1227 | "version-compare 0.2.0", 1228 | ] 1229 | 1230 | [[package]] 1231 | name = "target-lexicon" 1232 | version = "0.12.16" 1233 | source = "registry+https://github.com/rust-lang/crates.io-index" 1234 | checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" 1235 | 1236 | [[package]] 1237 | name = "tempfile" 1238 | version = "3.15.0" 1239 | source = "registry+https://github.com/rust-lang/crates.io-index" 1240 | checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" 1241 | dependencies = [ 1242 | "cfg-if", 1243 | "fastrand", 1244 | "getrandom", 1245 | "once_cell", 1246 | "rustix", 1247 | "windows-sys", 1248 | ] 1249 | 1250 | [[package]] 1251 | name = "thiserror" 1252 | version = "1.0.69" 1253 | source = "registry+https://github.com/rust-lang/crates.io-index" 1254 | checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" 1255 | dependencies = [ 1256 | "thiserror-impl", 1257 | ] 1258 | 1259 | [[package]] 1260 | name = "thiserror-impl" 1261 | version = "1.0.69" 1262 | source = "registry+https://github.com/rust-lang/crates.io-index" 1263 | checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" 1264 | dependencies = [ 1265 | "proc-macro2", 1266 | "quote", 1267 | "syn", 1268 | ] 1269 | 1270 | [[package]] 1271 | name = "tiff" 1272 | version = "0.9.1" 1273 | source = "registry+https://github.com/rust-lang/crates.io-index" 1274 | checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" 1275 | dependencies = [ 1276 | "flate2", 1277 | "jpeg-decoder", 1278 | "weezl", 1279 | ] 1280 | 1281 | [[package]] 1282 | name = "toml" 1283 | version = "0.8.19" 1284 | source = "registry+https://github.com/rust-lang/crates.io-index" 1285 | checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" 1286 | dependencies = [ 1287 | "serde", 1288 | "serde_spanned", 1289 | "toml_datetime", 1290 | "toml_edit", 1291 | ] 1292 | 1293 | [[package]] 1294 | name = "toml_datetime" 1295 | version = "0.6.8" 1296 | source = "registry+https://github.com/rust-lang/crates.io-index" 1297 | checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" 1298 | dependencies = [ 1299 | "serde", 1300 | ] 1301 | 1302 | [[package]] 1303 | name = "toml_edit" 1304 | version = "0.22.22" 1305 | source = "registry+https://github.com/rust-lang/crates.io-index" 1306 | checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" 1307 | dependencies = [ 1308 | "indexmap", 1309 | "serde", 1310 | "serde_spanned", 1311 | "toml_datetime", 1312 | "winnow", 1313 | ] 1314 | 1315 | [[package]] 1316 | name = "unicode-ident" 1317 | version = "1.0.14" 1318 | source = "registry+https://github.com/rust-lang/crates.io-index" 1319 | checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" 1320 | 1321 | [[package]] 1322 | name = "utf8parse" 1323 | version = "0.2.2" 1324 | source = "registry+https://github.com/rust-lang/crates.io-index" 1325 | checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 1326 | 1327 | [[package]] 1328 | name = "v_frame" 1329 | version = "0.3.8" 1330 | source = "registry+https://github.com/rust-lang/crates.io-index" 1331 | checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b" 1332 | dependencies = [ 1333 | "aligned-vec", 1334 | "num-traits", 1335 | "wasm-bindgen", 1336 | ] 1337 | 1338 | [[package]] 1339 | name = "version-compare" 1340 | version = "0.1.1" 1341 | source = "registry+https://github.com/rust-lang/crates.io-index" 1342 | checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" 1343 | 1344 | [[package]] 1345 | name = "version-compare" 1346 | version = "0.2.0" 1347 | source = "registry+https://github.com/rust-lang/crates.io-index" 1348 | checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" 1349 | 1350 | [[package]] 1351 | name = "wasi" 1352 | version = "0.11.0+wasi-snapshot-preview1" 1353 | source = "registry+https://github.com/rust-lang/crates.io-index" 1354 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1355 | 1356 | [[package]] 1357 | name = "wasm-bindgen" 1358 | version = "0.2.99" 1359 | source = "registry+https://github.com/rust-lang/crates.io-index" 1360 | checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" 1361 | dependencies = [ 1362 | "cfg-if", 1363 | "once_cell", 1364 | "wasm-bindgen-macro", 1365 | ] 1366 | 1367 | [[package]] 1368 | name = "wasm-bindgen-backend" 1369 | version = "0.2.99" 1370 | source = "registry+https://github.com/rust-lang/crates.io-index" 1371 | checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" 1372 | dependencies = [ 1373 | "bumpalo", 1374 | "log", 1375 | "proc-macro2", 1376 | "quote", 1377 | "syn", 1378 | "wasm-bindgen-shared", 1379 | ] 1380 | 1381 | [[package]] 1382 | name = "wasm-bindgen-futures" 1383 | version = "0.4.49" 1384 | source = "registry+https://github.com/rust-lang/crates.io-index" 1385 | checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" 1386 | dependencies = [ 1387 | "cfg-if", 1388 | "js-sys", 1389 | "once_cell", 1390 | "wasm-bindgen", 1391 | "web-sys", 1392 | ] 1393 | 1394 | [[package]] 1395 | name = "wasm-bindgen-macro" 1396 | version = "0.2.99" 1397 | source = "registry+https://github.com/rust-lang/crates.io-index" 1398 | checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" 1399 | dependencies = [ 1400 | "quote", 1401 | "wasm-bindgen-macro-support", 1402 | ] 1403 | 1404 | [[package]] 1405 | name = "wasm-bindgen-macro-support" 1406 | version = "0.2.99" 1407 | source = "registry+https://github.com/rust-lang/crates.io-index" 1408 | checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" 1409 | dependencies = [ 1410 | "proc-macro2", 1411 | "quote", 1412 | "syn", 1413 | "wasm-bindgen-backend", 1414 | "wasm-bindgen-shared", 1415 | ] 1416 | 1417 | [[package]] 1418 | name = "wasm-bindgen-shared" 1419 | version = "0.2.99" 1420 | source = "registry+https://github.com/rust-lang/crates.io-index" 1421 | checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" 1422 | 1423 | [[package]] 1424 | name = "wayland-client" 1425 | version = "0.29.5" 1426 | source = "registry+https://github.com/rust-lang/crates.io-index" 1427 | checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715" 1428 | dependencies = [ 1429 | "bitflags 1.3.2", 1430 | "downcast-rs", 1431 | "libc", 1432 | "nix", 1433 | "scoped-tls", 1434 | "wayland-commons", 1435 | "wayland-scanner", 1436 | "wayland-sys", 1437 | ] 1438 | 1439 | [[package]] 1440 | name = "wayland-commons" 1441 | version = "0.29.5" 1442 | source = "registry+https://github.com/rust-lang/crates.io-index" 1443 | checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902" 1444 | dependencies = [ 1445 | "nix", 1446 | "once_cell", 1447 | "smallvec", 1448 | "wayland-sys", 1449 | ] 1450 | 1451 | [[package]] 1452 | name = "wayland-cursor" 1453 | version = "0.29.5" 1454 | source = "registry+https://github.com/rust-lang/crates.io-index" 1455 | checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" 1456 | dependencies = [ 1457 | "nix", 1458 | "wayland-client", 1459 | "xcursor", 1460 | ] 1461 | 1462 | [[package]] 1463 | name = "wayland-protocols" 1464 | version = "0.29.5" 1465 | source = "registry+https://github.com/rust-lang/crates.io-index" 1466 | checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6" 1467 | dependencies = [ 1468 | "bitflags 1.3.2", 1469 | "wayland-client", 1470 | "wayland-commons", 1471 | "wayland-scanner", 1472 | ] 1473 | 1474 | [[package]] 1475 | name = "wayland-scanner" 1476 | version = "0.29.5" 1477 | source = "registry+https://github.com/rust-lang/crates.io-index" 1478 | checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53" 1479 | dependencies = [ 1480 | "proc-macro2", 1481 | "quote", 1482 | "xml-rs", 1483 | ] 1484 | 1485 | [[package]] 1486 | name = "wayland-sys" 1487 | version = "0.29.5" 1488 | source = "registry+https://github.com/rust-lang/crates.io-index" 1489 | checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4" 1490 | dependencies = [ 1491 | "dlib", 1492 | "lazy_static", 1493 | "pkg-config", 1494 | ] 1495 | 1496 | [[package]] 1497 | name = "web-sys" 1498 | version = "0.3.76" 1499 | source = "registry+https://github.com/rust-lang/crates.io-index" 1500 | checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" 1501 | dependencies = [ 1502 | "js-sys", 1503 | "wasm-bindgen", 1504 | ] 1505 | 1506 | [[package]] 1507 | name = "weezl" 1508 | version = "0.1.8" 1509 | source = "registry+https://github.com/rust-lang/crates.io-index" 1510 | checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" 1511 | 1512 | [[package]] 1513 | name = "winapi" 1514 | version = "0.3.9" 1515 | source = "registry+https://github.com/rust-lang/crates.io-index" 1516 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1517 | dependencies = [ 1518 | "winapi-i686-pc-windows-gnu", 1519 | "winapi-x86_64-pc-windows-gnu", 1520 | ] 1521 | 1522 | [[package]] 1523 | name = "winapi-i686-pc-windows-gnu" 1524 | version = "0.4.0" 1525 | source = "registry+https://github.com/rust-lang/crates.io-index" 1526 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1527 | 1528 | [[package]] 1529 | name = "winapi-x86_64-pc-windows-gnu" 1530 | version = "0.4.0" 1531 | source = "registry+https://github.com/rust-lang/crates.io-index" 1532 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1533 | 1534 | [[package]] 1535 | name = "windows-sys" 1536 | version = "0.59.0" 1537 | source = "registry+https://github.com/rust-lang/crates.io-index" 1538 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 1539 | dependencies = [ 1540 | "windows-targets", 1541 | ] 1542 | 1543 | [[package]] 1544 | name = "windows-targets" 1545 | version = "0.52.6" 1546 | source = "registry+https://github.com/rust-lang/crates.io-index" 1547 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 1548 | dependencies = [ 1549 | "windows_aarch64_gnullvm", 1550 | "windows_aarch64_msvc", 1551 | "windows_i686_gnu", 1552 | "windows_i686_gnullvm", 1553 | "windows_i686_msvc", 1554 | "windows_x86_64_gnu", 1555 | "windows_x86_64_gnullvm", 1556 | "windows_x86_64_msvc", 1557 | ] 1558 | 1559 | [[package]] 1560 | name = "windows_aarch64_gnullvm" 1561 | version = "0.52.6" 1562 | source = "registry+https://github.com/rust-lang/crates.io-index" 1563 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 1564 | 1565 | [[package]] 1566 | name = "windows_aarch64_msvc" 1567 | version = "0.52.6" 1568 | source = "registry+https://github.com/rust-lang/crates.io-index" 1569 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 1570 | 1571 | [[package]] 1572 | name = "windows_i686_gnu" 1573 | version = "0.52.6" 1574 | source = "registry+https://github.com/rust-lang/crates.io-index" 1575 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 1576 | 1577 | [[package]] 1578 | name = "windows_i686_gnullvm" 1579 | version = "0.52.6" 1580 | source = "registry+https://github.com/rust-lang/crates.io-index" 1581 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 1582 | 1583 | [[package]] 1584 | name = "windows_i686_msvc" 1585 | version = "0.52.6" 1586 | source = "registry+https://github.com/rust-lang/crates.io-index" 1587 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 1588 | 1589 | [[package]] 1590 | name = "windows_x86_64_gnu" 1591 | version = "0.52.6" 1592 | source = "registry+https://github.com/rust-lang/crates.io-index" 1593 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 1594 | 1595 | [[package]] 1596 | name = "windows_x86_64_gnullvm" 1597 | version = "0.52.6" 1598 | source = "registry+https://github.com/rust-lang/crates.io-index" 1599 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 1600 | 1601 | [[package]] 1602 | name = "windows_x86_64_msvc" 1603 | version = "0.52.6" 1604 | source = "registry+https://github.com/rust-lang/crates.io-index" 1605 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 1606 | 1607 | [[package]] 1608 | name = "winnow" 1609 | version = "0.6.22" 1610 | source = "registry+https://github.com/rust-lang/crates.io-index" 1611 | checksum = "39281189af81c07ec09db316b302a3e67bf9bd7cbf6c820b50e35fee9c2fa980" 1612 | dependencies = [ 1613 | "memchr", 1614 | ] 1615 | 1616 | [[package]] 1617 | name = "x11-dl" 1618 | version = "2.21.0" 1619 | source = "registry+https://github.com/rust-lang/crates.io-index" 1620 | checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" 1621 | dependencies = [ 1622 | "libc", 1623 | "once_cell", 1624 | "pkg-config", 1625 | ] 1626 | 1627 | [[package]] 1628 | name = "xcursor" 1629 | version = "0.3.8" 1630 | source = "registry+https://github.com/rust-lang/crates.io-index" 1631 | checksum = "0ef33da6b1660b4ddbfb3aef0ade110c8b8a781a3b6382fa5f2b5b040fd55f61" 1632 | 1633 | [[package]] 1634 | name = "xml-rs" 1635 | version = "0.8.25" 1636 | source = "registry+https://github.com/rust-lang/crates.io-index" 1637 | checksum = "c5b940ebc25896e71dd073bad2dbaa2abfe97b0a391415e22ad1326d9c54e3c4" 1638 | 1639 | [[package]] 1640 | name = "zerocopy" 1641 | version = "0.7.35" 1642 | source = "registry+https://github.com/rust-lang/crates.io-index" 1643 | checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" 1644 | dependencies = [ 1645 | "byteorder", 1646 | "zerocopy-derive", 1647 | ] 1648 | 1649 | [[package]] 1650 | name = "zerocopy-derive" 1651 | version = "0.7.35" 1652 | source = "registry+https://github.com/rust-lang/crates.io-index" 1653 | checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" 1654 | dependencies = [ 1655 | "proc-macro2", 1656 | "quote", 1657 | "syn", 1658 | ] 1659 | 1660 | [[package]] 1661 | name = "zune-core" 1662 | version = "0.4.12" 1663 | source = "registry+https://github.com/rust-lang/crates.io-index" 1664 | checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" 1665 | 1666 | [[package]] 1667 | name = "zune-inflate" 1668 | version = "0.2.54" 1669 | source = "registry+https://github.com/rust-lang/crates.io-index" 1670 | checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" 1671 | dependencies = [ 1672 | "simd-adler32", 1673 | ] 1674 | 1675 | [[package]] 1676 | name = "zune-jpeg" 1677 | version = "0.4.14" 1678 | source = "registry+https://github.com/rust-lang/crates.io-index" 1679 | checksum = "99a5bab8d7dedf81405c4bb1f2b83ea057643d9cb28778cea9eecddeedd2e028" 1680 | dependencies = [ 1681 | "zune-core", 1682 | ] 1683 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "linez" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | bresenham = "0.1.1" 8 | clap = { version = "4.5.24", features = ["derive"] } 9 | image = "0.25.5" 10 | minifb = "0.27" 11 | rand = "0.8.5" 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # linez 2 | 3 | Quick & fun tool that approximates images using lines: 4 | 5 |

6 | 7 |

8 | 9 |

10 | 11 |

12 | 13 |

14 | 15 |

16 | 17 | ## Usage 18 | 19 | ``` shell 20 | $ git clone https://github.com/Patryk27/linez 21 | $ cd linez 22 | $ cargo run --release -- images/starry-night.jpg 23 | # (press escape to close the app) 24 | ``` 25 | 26 | ## Algorithm 27 | 28 | 1. Load image provided by user (aka the target image). 29 | 2. Create a black image (aka the approximated image). 30 | 3. Sample a line: randomize starting point, ending point, and color. 31 | 4. Check if drawing this line on the approximated image would reduce _the distance_ between the approximated image and the target image. 32 | 5. If so, draw the line; otherwise don't draw it. 33 | 6. Go to 3. 34 | 35 | ... where "distance between images" is e.g. mean squared error: 36 | 37 | ``` 38 | fn image_distance(img_a, img_b): 39 | assert img_a.size() == img_b.size() 40 | 41 | dist = 0.0 42 | 43 | for all pixels in img_a and img_b: 44 | dist += pixel_distance(pixel_a, pixel_b) 45 | 46 | return dist 47 | 48 | fn pixel_distance(pixel_a, pixel_b): 49 | dist_r = (pixel_a.red - pixel_b.red) ^ 2 50 | dist_g = (pixel_a.green - pixel_b.green) ^ 2 51 | dist_b = (pixel_a.blue - pixel_b.blue) ^ 2 52 | 53 | return dist_r + dist_g + dist_b 54 | ``` 55 | 56 | ## License 57 | 58 | MIT License 59 | 60 | Copyright (c) 2024 Patryk Wychowaniec 61 | -------------------------------------------------------------------------------- /_readme/photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Patryk27/linez/dd54da36cbcfcacbc6e929c7a5f391424f9bfd9b/_readme/photo.jpg -------------------------------------------------------------------------------- /_readme/rust.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Patryk27/linez/dd54da36cbcfcacbc6e929c7a5f391424f9bfd9b/_readme/rust.jpg -------------------------------------------------------------------------------- /_readme/starry-night.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Patryk27/linez/dd54da36cbcfcacbc6e929c7a5f391424f9bfd9b/_readme/starry-night.jpg -------------------------------------------------------------------------------- /images/girl-with-a-pearl-earring.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Patryk27/linez/dd54da36cbcfcacbc6e929c7a5f391424f9bfd9b/images/girl-with-a-pearl-earring.jpg -------------------------------------------------------------------------------- /images/ophelia.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Patryk27/linez/dd54da36cbcfcacbc6e929c7a5f391424f9bfd9b/images/ophelia.jpg -------------------------------------------------------------------------------- /images/starry-night.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Patryk27/linez/dd54da36cbcfcacbc6e929c7a5f391424f9bfd9b/images/starry-night.jpg -------------------------------------------------------------------------------- /rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "1.84.0" 3 | -------------------------------------------------------------------------------- /shell.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs ? import { }, 3 | }: 4 | 5 | with pkgs; 6 | 7 | mkShell rec { 8 | nativeBuildInputs = [ 9 | pkg-config 10 | ]; 11 | 12 | buildInputs = [ 13 | udev 14 | alsa-lib 15 | vulkan-loader 16 | xorg.libX11 17 | xorg.libXcursor 18 | xorg.libXi 19 | xorg.libXrandr 20 | libxkbcommon 21 | wayland 22 | ]; 23 | 24 | LD_LIBRARY_PATH = lib.makeLibraryPath buildInputs; 25 | } 26 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use bresenham::Bresenham; 2 | use clap::Parser; 3 | use image::{ImageReader, RgbImage}; 4 | use minifb::{Key, Window, WindowOptions}; 5 | use rand::Rng; 6 | use rand::RngCore; 7 | use std::path::PathBuf; 8 | 9 | #[derive(Parser)] 10 | struct Args { 11 | target: PathBuf, 12 | 13 | #[clap(short, long, default_value = "4096")] 14 | iterations: usize, 15 | 16 | #[clap(short, long)] 17 | output: Option, 18 | } 19 | 20 | fn main() { 21 | let args = Args::parse(); 22 | 23 | // --- 24 | 25 | let target = ImageReader::open(args.target) 26 | .expect("couldn't load given image") 27 | .decode() 28 | .expect("couldn't decode given image") 29 | .into_rgb8(); 30 | 31 | let target = Image::from(target); 32 | let width = target.width; 33 | let height = target.height; 34 | 35 | let mut approx = Image::from(RgbImage::new(width, height)); 36 | 37 | // --- 38 | 39 | let mut rng = rand::thread_rng(); 40 | let mut canvas = vec![0; (width * height) as usize]; 41 | 42 | let mut window = Window::new( 43 | "linez", 44 | width as usize, 45 | height as usize, 46 | WindowOptions::default(), 47 | ) 48 | .unwrap(); 49 | 50 | while window.is_open() && !window.is_key_down(Key::Escape) { 51 | let mut got_improvement = false; 52 | 53 | for _ in 0..args.iterations { 54 | got_improvement |= tick(&mut rng, &target, &mut approx); 55 | } 56 | 57 | if got_improvement { 58 | approx.encode(&mut canvas); 59 | } 60 | 61 | window 62 | .update_with_buffer(&canvas, width as usize, height as usize) 63 | .unwrap(); 64 | } 65 | 66 | if let Some(output_path) = args.output { 67 | let final_image: RgbImage = approx.into(); 68 | final_image 69 | .save(output_path) 70 | .expect("couldn't save final image"); 71 | } 72 | } 73 | 74 | fn tick(rng: &mut impl RngCore, target: &Image, approx: &mut Image) -> bool { 75 | // Randomize starting point 76 | let beg_x = rng.gen_range(0..target.width) as isize; 77 | let beg_y = rng.gen_range(0..target.height) as isize; 78 | 79 | // Randomize ending point 80 | let end_x = rng.gen_range(0..target.width) as isize; 81 | let end_y = rng.gen_range(0..target.height) as isize; 82 | 83 | // Randomize color 84 | let r = rng.gen_range(0..255); 85 | let g = rng.gen_range(0..255); 86 | let b = rng.gen_range(0..255); 87 | 88 | // Prepare changes required to draw the line. 89 | // 90 | // We're using a closure, since `Bresenham` is not `Clone`-able and, for 91 | // performance reasons, we'd like to avoid `.collect()`-ing the temporary 92 | // points here. 93 | let changes = || { 94 | Bresenham::new((beg_x, beg_y), (end_x, end_y)) 95 | .map(|(x, y)| [x as u32, y as u32]) 96 | .map(|pos| (pos, [r, g, b])) 97 | }; 98 | 99 | // Check if `approx + changes()` brings us "closer" towards `target` 100 | let loss_delta = Image::loss_delta(target, approx, changes()); 101 | 102 | // ... if not, bail out 103 | if loss_delta >= 0.0 { 104 | return false; 105 | } 106 | 107 | // ... and otherwise apply the changes, i.e. draw the line 108 | approx.apply(changes()); 109 | 110 | true 111 | } 112 | 113 | type Point = [u32; 2]; 114 | type Color = [u8; 3]; 115 | 116 | struct Image { 117 | width: u32, 118 | height: u32, 119 | pixels: Vec, 120 | } 121 | 122 | impl Image { 123 | /// Calculates how good `approx + changes` approximates `target`, i.e. we 124 | /// evaluate `Δ distance(target, approx + changes)` in color space. 125 | /// 126 | /// Intuitively, if this function returns a *negative* value, it means that 127 | /// `approx + changes` approximates `target` *better* than just `approx` and 128 | /// so it makes sense to apply `changes` on `approx`. 129 | /// 130 | /// (negative = better, since we expect the loss to converge to zero over 131 | /// infinite time.) 132 | /// 133 | /// Note that we're interested only in the *change* of the loss - we don't 134 | /// care whether the absolute value of loss is 123.0 or 321.0, just whether 135 | /// `approx + changes` gets us closer towards `target`, even if only by a 136 | /// slight margin. 137 | /// 138 | /// Calculating absolute loss would require going through all of the pixels 139 | /// and that'd be wasteful, since we don't care about the precise value of 140 | /// the loss. 141 | fn loss_delta( 142 | target: &Self, 143 | approx: &Self, 144 | changes: impl IntoIterator, 145 | ) -> f32 { 146 | changes 147 | .into_iter() 148 | .map(|(pos, new_color)| { 149 | let target_color = target.color_at(pos); 150 | let approx_color = approx.color_at(pos); 151 | 152 | let loss_without_changes = Self::pixel_loss(target_color, approx_color); 153 | let loss_with_changes = Self::pixel_loss(target_color, new_color); 154 | 155 | loss_with_changes - loss_without_changes 156 | }) 157 | .sum() 158 | } 159 | 160 | /// Calculates how far apart `a` is from `b`. 161 | /// 162 | /// We use mean squared error, which is basically squared Euclidian distance 163 | /// between the channels of given RGB colors. 164 | /// 165 | /// Note that since RGB is not a perceptual color model¹, calculating loss 166 | /// this way is not ideal - but it's good enough. 167 | /// 168 | /// ¹ distances in RGB space don't correspond to how humans perceive 169 | /// distances between colors, e.g. compare with CIELab. 170 | fn pixel_loss(a: Color, b: Color) -> f32 { 171 | a.into_iter() 172 | .zip(b) 173 | .map(|(a, b)| (a as f32 - b as f32).powi(2)) 174 | .sum() 175 | } 176 | 177 | fn apply(&mut self, changes: impl IntoIterator) { 178 | for (pos, col) in changes { 179 | *self.color_at_mut(pos) = col; 180 | } 181 | } 182 | 183 | fn encode(&self, buf: &mut [u32]) { 184 | let mut buf = buf.iter_mut(); 185 | 186 | for y in 0..self.height { 187 | for x in 0..self.width { 188 | let [r, g, b] = self.color_at([x, y]); 189 | 190 | *buf.next().unwrap() = u32::from_be_bytes([0, r, g, b]); 191 | } 192 | } 193 | } 194 | 195 | fn color_at(&self, point: Point) -> Color { 196 | let offset = (point[1] * self.width + point[0]) as usize * 3; 197 | let color = &self.pixels[offset..][..3]; 198 | 199 | color.try_into().unwrap() 200 | } 201 | 202 | fn color_at_mut(&mut self, [x, y]: [u32; 2]) -> &mut Color { 203 | let offset = (y * self.width + x) as usize * 3; 204 | let color = &mut self.pixels[offset..][..3]; 205 | 206 | color.try_into().unwrap() 207 | } 208 | } 209 | 210 | impl From for Image { 211 | fn from(img: RgbImage) -> Self { 212 | let width = img.width(); 213 | let height = img.height(); 214 | let pixels = img.pixels().flat_map(|pixel| pixel.0).collect(); 215 | 216 | Self { 217 | width, 218 | height, 219 | pixels, 220 | } 221 | } 222 | } 223 | 224 | impl From for RgbImage { 225 | fn from(img: Image) -> Self { 226 | RgbImage::from_fn(img.width, img.height, |x, y| { 227 | image::Rgb(img.color_at([x, y])) 228 | }) 229 | } 230 | } 231 | --------------------------------------------------------------------------------