├── .gitignore
├── Cargo.lock
├── Cargo.toml
├── LICENSE-APACHE
├── LICENSE-MIT
├── README.md
├── flake.lock
├── flake.nix
├── images
├── dipc_dark.png
├── dipc_examples.png
└── dipc_light.png
└── src
├── cli.rs
├── config.rs
├── delta.rs
├── main.rs
├── palettes.rs
└── palettes
├── catppuccin.json
├── dracula.json
├── edge.json
├── everforest.json
├── gruvbox-material.json
├── gruvbox.json
├── nord.json
├── onedark.json
├── rose-pine.json
├── solarized.json
└── tokyo-night.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # Generated by Cargo
2 | # will have compiled files and executables
3 | debug/
4 | target/
5 |
6 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
7 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
8 | # Cargo.lock
9 |
10 | # These are backup files generated by rustfmt
11 | **/*.rs.bk
12 |
13 | # MSVC Windows builds of rustc generate these, which store debugging information
14 | *.pdb
15 |
--------------------------------------------------------------------------------
/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.7"
59 | source = "registry+https://github.com/rust-lang/crates.io-index"
60 | checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
61 | dependencies = [
62 | "anstyle",
63 | "once_cell",
64 | "windows-sys",
65 | ]
66 |
67 | [[package]]
68 | name = "anyhow"
69 | version = "1.0.98"
70 | source = "registry+https://github.com/rust-lang/crates.io-index"
71 | checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
72 |
73 | [[package]]
74 | name = "arbitrary"
75 | version = "1.4.1"
76 | source = "registry+https://github.com/rust-lang/crates.io-index"
77 | checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223"
78 |
79 | [[package]]
80 | name = "arg_enum_proc_macro"
81 | version = "0.3.4"
82 | source = "registry+https://github.com/rust-lang/crates.io-index"
83 | checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea"
84 | dependencies = [
85 | "proc-macro2",
86 | "quote",
87 | "syn",
88 | ]
89 |
90 | [[package]]
91 | name = "arrayvec"
92 | version = "0.7.6"
93 | source = "registry+https://github.com/rust-lang/crates.io-index"
94 | checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
95 |
96 | [[package]]
97 | name = "autocfg"
98 | version = "1.4.0"
99 | source = "registry+https://github.com/rust-lang/crates.io-index"
100 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
101 |
102 | [[package]]
103 | name = "av1-grain"
104 | version = "0.2.3"
105 | source = "registry+https://github.com/rust-lang/crates.io-index"
106 | checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf"
107 | dependencies = [
108 | "anyhow",
109 | "arrayvec",
110 | "log",
111 | "nom",
112 | "num-rational",
113 | "v_frame",
114 | ]
115 |
116 | [[package]]
117 | name = "avif-serialize"
118 | version = "0.8.3"
119 | source = "registry+https://github.com/rust-lang/crates.io-index"
120 | checksum = "98922d6a4cfbcb08820c69d8eeccc05bb1f29bfa06b4f5b1dbfe9a868bd7608e"
121 | dependencies = [
122 | "arrayvec",
123 | ]
124 |
125 | [[package]]
126 | name = "bit_field"
127 | version = "0.10.2"
128 | source = "registry+https://github.com/rust-lang/crates.io-index"
129 | checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
130 |
131 | [[package]]
132 | name = "bitflags"
133 | version = "1.3.2"
134 | source = "registry+https://github.com/rust-lang/crates.io-index"
135 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
136 |
137 | [[package]]
138 | name = "bitflags"
139 | version = "2.9.0"
140 | source = "registry+https://github.com/rust-lang/crates.io-index"
141 | checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
142 |
143 | [[package]]
144 | name = "bitstream-io"
145 | version = "2.6.0"
146 | source = "registry+https://github.com/rust-lang/crates.io-index"
147 | checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2"
148 |
149 | [[package]]
150 | name = "built"
151 | version = "0.7.7"
152 | source = "registry+https://github.com/rust-lang/crates.io-index"
153 | checksum = "56ed6191a7e78c36abdb16ab65341eefd73d64d303fffccdbb00d51e4205967b"
154 |
155 | [[package]]
156 | name = "bumpalo"
157 | version = "3.17.0"
158 | source = "registry+https://github.com/rust-lang/crates.io-index"
159 | checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
160 |
161 | [[package]]
162 | name = "bytemuck"
163 | version = "1.22.0"
164 | source = "registry+https://github.com/rust-lang/crates.io-index"
165 | checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540"
166 |
167 | [[package]]
168 | name = "byteorder-lite"
169 | version = "0.1.0"
170 | source = "registry+https://github.com/rust-lang/crates.io-index"
171 | checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
172 |
173 | [[package]]
174 | name = "cc"
175 | version = "1.2.19"
176 | source = "registry+https://github.com/rust-lang/crates.io-index"
177 | checksum = "8e3a13707ac958681c13b39b458c073d0d9bc8a22cb1b2f4c8e55eb72c13f362"
178 | dependencies = [
179 | "jobserver",
180 | "libc",
181 | "shlex",
182 | ]
183 |
184 | [[package]]
185 | name = "cfg-expr"
186 | version = "0.15.8"
187 | source = "registry+https://github.com/rust-lang/crates.io-index"
188 | checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02"
189 | dependencies = [
190 | "smallvec",
191 | "target-lexicon",
192 | ]
193 |
194 | [[package]]
195 | name = "cfg-if"
196 | version = "1.0.0"
197 | source = "registry+https://github.com/rust-lang/crates.io-index"
198 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
199 |
200 | [[package]]
201 | name = "clap"
202 | version = "4.5.37"
203 | source = "registry+https://github.com/rust-lang/crates.io-index"
204 | checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071"
205 | dependencies = [
206 | "clap_builder",
207 | "clap_derive",
208 | ]
209 |
210 | [[package]]
211 | name = "clap_builder"
212 | version = "4.5.37"
213 | source = "registry+https://github.com/rust-lang/crates.io-index"
214 | checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2"
215 | dependencies = [
216 | "anstream",
217 | "anstyle",
218 | "clap_lex",
219 | "strsim",
220 | ]
221 |
222 | [[package]]
223 | name = "clap_derive"
224 | version = "4.5.32"
225 | source = "registry+https://github.com/rust-lang/crates.io-index"
226 | checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7"
227 | dependencies = [
228 | "heck",
229 | "proc-macro2",
230 | "quote",
231 | "syn",
232 | ]
233 |
234 | [[package]]
235 | name = "clap_lex"
236 | version = "0.7.4"
237 | source = "registry+https://github.com/rust-lang/crates.io-index"
238 | checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
239 |
240 | [[package]]
241 | name = "color_quant"
242 | version = "1.1.0"
243 | source = "registry+https://github.com/rust-lang/crates.io-index"
244 | checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
245 |
246 | [[package]]
247 | name = "colorchoice"
248 | version = "1.0.3"
249 | source = "registry+https://github.com/rust-lang/crates.io-index"
250 | checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
251 |
252 | [[package]]
253 | name = "console"
254 | version = "0.15.11"
255 | source = "registry+https://github.com/rust-lang/crates.io-index"
256 | checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8"
257 | dependencies = [
258 | "encode_unicode",
259 | "libc",
260 | "once_cell",
261 | "unicode-width",
262 | "windows-sys",
263 | ]
264 |
265 | [[package]]
266 | name = "crc32fast"
267 | version = "1.4.2"
268 | source = "registry+https://github.com/rust-lang/crates.io-index"
269 | checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
270 | dependencies = [
271 | "cfg-if",
272 | ]
273 |
274 | [[package]]
275 | name = "crossbeam-deque"
276 | version = "0.8.6"
277 | source = "registry+https://github.com/rust-lang/crates.io-index"
278 | checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
279 | dependencies = [
280 | "crossbeam-epoch",
281 | "crossbeam-utils",
282 | ]
283 |
284 | [[package]]
285 | name = "crossbeam-epoch"
286 | version = "0.9.18"
287 | source = "registry+https://github.com/rust-lang/crates.io-index"
288 | checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
289 | dependencies = [
290 | "crossbeam-utils",
291 | ]
292 |
293 | [[package]]
294 | name = "crossbeam-utils"
295 | version = "0.8.21"
296 | source = "registry+https://github.com/rust-lang/crates.io-index"
297 | checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
298 |
299 | [[package]]
300 | name = "crunchy"
301 | version = "0.2.3"
302 | source = "registry+https://github.com/rust-lang/crates.io-index"
303 | checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929"
304 |
305 | [[package]]
306 | name = "deltae"
307 | version = "0.3.2"
308 | source = "registry+https://github.com/rust-lang/crates.io-index"
309 | checksum = "5729f5117e208430e437df2f4843f5e5952997175992d1414f94c57d61e270b4"
310 |
311 | [[package]]
312 | name = "dipc"
313 | version = "1.0.0"
314 | dependencies = [
315 | "clap",
316 | "deltae",
317 | "image",
318 | "indicatif",
319 | "lab",
320 | "owo-colors",
321 | "rayon",
322 | "serde_json",
323 | "supports-color 3.0.2",
324 | ]
325 |
326 | [[package]]
327 | name = "either"
328 | version = "1.15.0"
329 | source = "registry+https://github.com/rust-lang/crates.io-index"
330 | checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
331 |
332 | [[package]]
333 | name = "encode_unicode"
334 | version = "1.0.0"
335 | source = "registry+https://github.com/rust-lang/crates.io-index"
336 | checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
337 |
338 | [[package]]
339 | name = "equivalent"
340 | version = "1.0.2"
341 | source = "registry+https://github.com/rust-lang/crates.io-index"
342 | checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
343 |
344 | [[package]]
345 | name = "exr"
346 | version = "1.73.0"
347 | source = "registry+https://github.com/rust-lang/crates.io-index"
348 | checksum = "f83197f59927b46c04a183a619b7c29df34e63e63c7869320862268c0ef687e0"
349 | dependencies = [
350 | "bit_field",
351 | "half",
352 | "lebe",
353 | "miniz_oxide",
354 | "rayon-core",
355 | "smallvec",
356 | "zune-inflate",
357 | ]
358 |
359 | [[package]]
360 | name = "fdeflate"
361 | version = "0.3.7"
362 | source = "registry+https://github.com/rust-lang/crates.io-index"
363 | checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c"
364 | dependencies = [
365 | "simd-adler32",
366 | ]
367 |
368 | [[package]]
369 | name = "flate2"
370 | version = "1.1.1"
371 | source = "registry+https://github.com/rust-lang/crates.io-index"
372 | checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece"
373 | dependencies = [
374 | "crc32fast",
375 | "miniz_oxide",
376 | ]
377 |
378 | [[package]]
379 | name = "getrandom"
380 | version = "0.2.16"
381 | source = "registry+https://github.com/rust-lang/crates.io-index"
382 | checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
383 | dependencies = [
384 | "cfg-if",
385 | "libc",
386 | "wasi 0.11.0+wasi-snapshot-preview1",
387 | ]
388 |
389 | [[package]]
390 | name = "getrandom"
391 | version = "0.3.2"
392 | source = "registry+https://github.com/rust-lang/crates.io-index"
393 | checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
394 | dependencies = [
395 | "cfg-if",
396 | "libc",
397 | "r-efi",
398 | "wasi 0.14.2+wasi-0.2.4",
399 | ]
400 |
401 | [[package]]
402 | name = "gif"
403 | version = "0.13.1"
404 | source = "registry+https://github.com/rust-lang/crates.io-index"
405 | checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2"
406 | dependencies = [
407 | "color_quant",
408 | "weezl",
409 | ]
410 |
411 | [[package]]
412 | name = "half"
413 | version = "2.6.0"
414 | source = "registry+https://github.com/rust-lang/crates.io-index"
415 | checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9"
416 | dependencies = [
417 | "cfg-if",
418 | "crunchy",
419 | ]
420 |
421 | [[package]]
422 | name = "hashbrown"
423 | version = "0.15.2"
424 | source = "registry+https://github.com/rust-lang/crates.io-index"
425 | checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
426 |
427 | [[package]]
428 | name = "heck"
429 | version = "0.5.0"
430 | source = "registry+https://github.com/rust-lang/crates.io-index"
431 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
432 |
433 | [[package]]
434 | name = "hermit-abi"
435 | version = "0.5.0"
436 | source = "registry+https://github.com/rust-lang/crates.io-index"
437 | checksum = "fbd780fe5cc30f81464441920d82ac8740e2e46b29a6fad543ddd075229ce37e"
438 |
439 | [[package]]
440 | name = "image"
441 | version = "0.25.6"
442 | source = "registry+https://github.com/rust-lang/crates.io-index"
443 | checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a"
444 | dependencies = [
445 | "bytemuck",
446 | "byteorder-lite",
447 | "color_quant",
448 | "exr",
449 | "gif",
450 | "image-webp",
451 | "num-traits",
452 | "png",
453 | "qoi",
454 | "ravif",
455 | "rayon",
456 | "rgb",
457 | "tiff",
458 | "zune-core",
459 | "zune-jpeg",
460 | ]
461 |
462 | [[package]]
463 | name = "image-webp"
464 | version = "0.2.1"
465 | source = "registry+https://github.com/rust-lang/crates.io-index"
466 | checksum = "b77d01e822461baa8409e156015a1d91735549f0f2c17691bd2d996bef238f7f"
467 | dependencies = [
468 | "byteorder-lite",
469 | "quick-error",
470 | ]
471 |
472 | [[package]]
473 | name = "imgref"
474 | version = "1.11.0"
475 | source = "registry+https://github.com/rust-lang/crates.io-index"
476 | checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408"
477 |
478 | [[package]]
479 | name = "indexmap"
480 | version = "2.9.0"
481 | source = "registry+https://github.com/rust-lang/crates.io-index"
482 | checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
483 | dependencies = [
484 | "equivalent",
485 | "hashbrown",
486 | ]
487 |
488 | [[package]]
489 | name = "indicatif"
490 | version = "0.17.11"
491 | source = "registry+https://github.com/rust-lang/crates.io-index"
492 | checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235"
493 | dependencies = [
494 | "console",
495 | "number_prefix",
496 | "portable-atomic",
497 | "rayon",
498 | "unicode-width",
499 | "web-time",
500 | ]
501 |
502 | [[package]]
503 | name = "interpolate_name"
504 | version = "0.2.4"
505 | source = "registry+https://github.com/rust-lang/crates.io-index"
506 | checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60"
507 | dependencies = [
508 | "proc-macro2",
509 | "quote",
510 | "syn",
511 | ]
512 |
513 | [[package]]
514 | name = "is-terminal"
515 | version = "0.4.16"
516 | source = "registry+https://github.com/rust-lang/crates.io-index"
517 | checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
518 | dependencies = [
519 | "hermit-abi",
520 | "libc",
521 | "windows-sys",
522 | ]
523 |
524 | [[package]]
525 | name = "is_ci"
526 | version = "1.2.0"
527 | source = "registry+https://github.com/rust-lang/crates.io-index"
528 | checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45"
529 |
530 | [[package]]
531 | name = "is_terminal_polyfill"
532 | version = "1.70.1"
533 | source = "registry+https://github.com/rust-lang/crates.io-index"
534 | checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
535 |
536 | [[package]]
537 | name = "itertools"
538 | version = "0.12.1"
539 | source = "registry+https://github.com/rust-lang/crates.io-index"
540 | checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
541 | dependencies = [
542 | "either",
543 | ]
544 |
545 | [[package]]
546 | name = "itoa"
547 | version = "1.0.15"
548 | source = "registry+https://github.com/rust-lang/crates.io-index"
549 | checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
550 |
551 | [[package]]
552 | name = "jobserver"
553 | version = "0.1.33"
554 | source = "registry+https://github.com/rust-lang/crates.io-index"
555 | checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a"
556 | dependencies = [
557 | "getrandom 0.3.2",
558 | "libc",
559 | ]
560 |
561 | [[package]]
562 | name = "jpeg-decoder"
563 | version = "0.3.1"
564 | source = "registry+https://github.com/rust-lang/crates.io-index"
565 | checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0"
566 |
567 | [[package]]
568 | name = "js-sys"
569 | version = "0.3.77"
570 | source = "registry+https://github.com/rust-lang/crates.io-index"
571 | checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
572 | dependencies = [
573 | "once_cell",
574 | "wasm-bindgen",
575 | ]
576 |
577 | [[package]]
578 | name = "lab"
579 | version = "0.11.0"
580 | source = "registry+https://github.com/rust-lang/crates.io-index"
581 | checksum = "bf36173d4167ed999940f804952e6b08197cae5ad5d572eb4db150ce8ad5d58f"
582 |
583 | [[package]]
584 | name = "lebe"
585 | version = "0.5.2"
586 | source = "registry+https://github.com/rust-lang/crates.io-index"
587 | checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
588 |
589 | [[package]]
590 | name = "libc"
591 | version = "0.2.172"
592 | source = "registry+https://github.com/rust-lang/crates.io-index"
593 | checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
594 |
595 | [[package]]
596 | name = "libfuzzer-sys"
597 | version = "0.4.9"
598 | source = "registry+https://github.com/rust-lang/crates.io-index"
599 | checksum = "cf78f52d400cf2d84a3a973a78a592b4adc535739e0a5597a0da6f0c357adc75"
600 | dependencies = [
601 | "arbitrary",
602 | "cc",
603 | ]
604 |
605 | [[package]]
606 | name = "log"
607 | version = "0.4.27"
608 | source = "registry+https://github.com/rust-lang/crates.io-index"
609 | checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
610 |
611 | [[package]]
612 | name = "loop9"
613 | version = "0.1.5"
614 | source = "registry+https://github.com/rust-lang/crates.io-index"
615 | checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062"
616 | dependencies = [
617 | "imgref",
618 | ]
619 |
620 | [[package]]
621 | name = "maybe-rayon"
622 | version = "0.1.1"
623 | source = "registry+https://github.com/rust-lang/crates.io-index"
624 | checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519"
625 | dependencies = [
626 | "cfg-if",
627 | "rayon",
628 | ]
629 |
630 | [[package]]
631 | name = "memchr"
632 | version = "2.7.4"
633 | source = "registry+https://github.com/rust-lang/crates.io-index"
634 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
635 |
636 | [[package]]
637 | name = "minimal-lexical"
638 | version = "0.2.1"
639 | source = "registry+https://github.com/rust-lang/crates.io-index"
640 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
641 |
642 | [[package]]
643 | name = "miniz_oxide"
644 | version = "0.8.8"
645 | source = "registry+https://github.com/rust-lang/crates.io-index"
646 | checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a"
647 | dependencies = [
648 | "adler2",
649 | "simd-adler32",
650 | ]
651 |
652 | [[package]]
653 | name = "new_debug_unreachable"
654 | version = "1.0.6"
655 | source = "registry+https://github.com/rust-lang/crates.io-index"
656 | checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
657 |
658 | [[package]]
659 | name = "nom"
660 | version = "7.1.3"
661 | source = "registry+https://github.com/rust-lang/crates.io-index"
662 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
663 | dependencies = [
664 | "memchr",
665 | "minimal-lexical",
666 | ]
667 |
668 | [[package]]
669 | name = "noop_proc_macro"
670 | version = "0.3.0"
671 | source = "registry+https://github.com/rust-lang/crates.io-index"
672 | checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8"
673 |
674 | [[package]]
675 | name = "num-bigint"
676 | version = "0.4.6"
677 | source = "registry+https://github.com/rust-lang/crates.io-index"
678 | checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
679 | dependencies = [
680 | "num-integer",
681 | "num-traits",
682 | ]
683 |
684 | [[package]]
685 | name = "num-derive"
686 | version = "0.4.2"
687 | source = "registry+https://github.com/rust-lang/crates.io-index"
688 | checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
689 | dependencies = [
690 | "proc-macro2",
691 | "quote",
692 | "syn",
693 | ]
694 |
695 | [[package]]
696 | name = "num-integer"
697 | version = "0.1.46"
698 | source = "registry+https://github.com/rust-lang/crates.io-index"
699 | checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
700 | dependencies = [
701 | "num-traits",
702 | ]
703 |
704 | [[package]]
705 | name = "num-rational"
706 | version = "0.4.2"
707 | source = "registry+https://github.com/rust-lang/crates.io-index"
708 | checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
709 | dependencies = [
710 | "num-bigint",
711 | "num-integer",
712 | "num-traits",
713 | ]
714 |
715 | [[package]]
716 | name = "num-traits"
717 | version = "0.2.19"
718 | source = "registry+https://github.com/rust-lang/crates.io-index"
719 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
720 | dependencies = [
721 | "autocfg",
722 | ]
723 |
724 | [[package]]
725 | name = "number_prefix"
726 | version = "0.4.0"
727 | source = "registry+https://github.com/rust-lang/crates.io-index"
728 | checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
729 |
730 | [[package]]
731 | name = "once_cell"
732 | version = "1.21.3"
733 | source = "registry+https://github.com/rust-lang/crates.io-index"
734 | checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
735 |
736 | [[package]]
737 | name = "owo-colors"
738 | version = "4.2.0"
739 | source = "registry+https://github.com/rust-lang/crates.io-index"
740 | checksum = "1036865bb9422d3300cf723f657c2851d0e9ab12567854b1f4eba3d77decf564"
741 | dependencies = [
742 | "supports-color 2.1.0",
743 | "supports-color 3.0.2",
744 | ]
745 |
746 | [[package]]
747 | name = "paste"
748 | version = "1.0.15"
749 | source = "registry+https://github.com/rust-lang/crates.io-index"
750 | checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
751 |
752 | [[package]]
753 | name = "pkg-config"
754 | version = "0.3.32"
755 | source = "registry+https://github.com/rust-lang/crates.io-index"
756 | checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
757 |
758 | [[package]]
759 | name = "png"
760 | version = "0.17.16"
761 | source = "registry+https://github.com/rust-lang/crates.io-index"
762 | checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526"
763 | dependencies = [
764 | "bitflags 1.3.2",
765 | "crc32fast",
766 | "fdeflate",
767 | "flate2",
768 | "miniz_oxide",
769 | ]
770 |
771 | [[package]]
772 | name = "portable-atomic"
773 | version = "1.11.0"
774 | source = "registry+https://github.com/rust-lang/crates.io-index"
775 | checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
776 |
777 | [[package]]
778 | name = "ppv-lite86"
779 | version = "0.2.21"
780 | source = "registry+https://github.com/rust-lang/crates.io-index"
781 | checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
782 | dependencies = [
783 | "zerocopy",
784 | ]
785 |
786 | [[package]]
787 | name = "proc-macro2"
788 | version = "1.0.95"
789 | source = "registry+https://github.com/rust-lang/crates.io-index"
790 | checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
791 | dependencies = [
792 | "unicode-ident",
793 | ]
794 |
795 | [[package]]
796 | name = "profiling"
797 | version = "1.0.16"
798 | source = "registry+https://github.com/rust-lang/crates.io-index"
799 | checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d"
800 | dependencies = [
801 | "profiling-procmacros",
802 | ]
803 |
804 | [[package]]
805 | name = "profiling-procmacros"
806 | version = "1.0.16"
807 | source = "registry+https://github.com/rust-lang/crates.io-index"
808 | checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30"
809 | dependencies = [
810 | "quote",
811 | "syn",
812 | ]
813 |
814 | [[package]]
815 | name = "qoi"
816 | version = "0.4.1"
817 | source = "registry+https://github.com/rust-lang/crates.io-index"
818 | checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001"
819 | dependencies = [
820 | "bytemuck",
821 | ]
822 |
823 | [[package]]
824 | name = "quick-error"
825 | version = "2.0.1"
826 | source = "registry+https://github.com/rust-lang/crates.io-index"
827 | checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
828 |
829 | [[package]]
830 | name = "quote"
831 | version = "1.0.40"
832 | source = "registry+https://github.com/rust-lang/crates.io-index"
833 | checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
834 | dependencies = [
835 | "proc-macro2",
836 | ]
837 |
838 | [[package]]
839 | name = "r-efi"
840 | version = "5.2.0"
841 | source = "registry+https://github.com/rust-lang/crates.io-index"
842 | checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
843 |
844 | [[package]]
845 | name = "rand"
846 | version = "0.8.5"
847 | source = "registry+https://github.com/rust-lang/crates.io-index"
848 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
849 | dependencies = [
850 | "libc",
851 | "rand_chacha",
852 | "rand_core",
853 | ]
854 |
855 | [[package]]
856 | name = "rand_chacha"
857 | version = "0.3.1"
858 | source = "registry+https://github.com/rust-lang/crates.io-index"
859 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
860 | dependencies = [
861 | "ppv-lite86",
862 | "rand_core",
863 | ]
864 |
865 | [[package]]
866 | name = "rand_core"
867 | version = "0.6.4"
868 | source = "registry+https://github.com/rust-lang/crates.io-index"
869 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
870 | dependencies = [
871 | "getrandom 0.2.16",
872 | ]
873 |
874 | [[package]]
875 | name = "rav1e"
876 | version = "0.7.1"
877 | source = "registry+https://github.com/rust-lang/crates.io-index"
878 | checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9"
879 | dependencies = [
880 | "arbitrary",
881 | "arg_enum_proc_macro",
882 | "arrayvec",
883 | "av1-grain",
884 | "bitstream-io",
885 | "built",
886 | "cfg-if",
887 | "interpolate_name",
888 | "itertools",
889 | "libc",
890 | "libfuzzer-sys",
891 | "log",
892 | "maybe-rayon",
893 | "new_debug_unreachable",
894 | "noop_proc_macro",
895 | "num-derive",
896 | "num-traits",
897 | "once_cell",
898 | "paste",
899 | "profiling",
900 | "rand",
901 | "rand_chacha",
902 | "simd_helpers",
903 | "system-deps",
904 | "thiserror",
905 | "v_frame",
906 | "wasm-bindgen",
907 | ]
908 |
909 | [[package]]
910 | name = "ravif"
911 | version = "0.11.12"
912 | source = "registry+https://github.com/rust-lang/crates.io-index"
913 | checksum = "d6a5f31fcf7500f9401fea858ea4ab5525c99f2322cfcee732c0e6c74208c0c6"
914 | dependencies = [
915 | "avif-serialize",
916 | "imgref",
917 | "loop9",
918 | "quick-error",
919 | "rav1e",
920 | "rayon",
921 | "rgb",
922 | ]
923 |
924 | [[package]]
925 | name = "rayon"
926 | version = "1.10.0"
927 | source = "registry+https://github.com/rust-lang/crates.io-index"
928 | checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
929 | dependencies = [
930 | "either",
931 | "rayon-core",
932 | ]
933 |
934 | [[package]]
935 | name = "rayon-core"
936 | version = "1.12.1"
937 | source = "registry+https://github.com/rust-lang/crates.io-index"
938 | checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
939 | dependencies = [
940 | "crossbeam-deque",
941 | "crossbeam-utils",
942 | ]
943 |
944 | [[package]]
945 | name = "rgb"
946 | version = "0.8.50"
947 | source = "registry+https://github.com/rust-lang/crates.io-index"
948 | checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a"
949 |
950 | [[package]]
951 | name = "rustversion"
952 | version = "1.0.20"
953 | source = "registry+https://github.com/rust-lang/crates.io-index"
954 | checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
955 |
956 | [[package]]
957 | name = "ryu"
958 | version = "1.0.20"
959 | source = "registry+https://github.com/rust-lang/crates.io-index"
960 | checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
961 |
962 | [[package]]
963 | name = "serde"
964 | version = "1.0.219"
965 | source = "registry+https://github.com/rust-lang/crates.io-index"
966 | checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
967 | dependencies = [
968 | "serde_derive",
969 | ]
970 |
971 | [[package]]
972 | name = "serde_derive"
973 | version = "1.0.219"
974 | source = "registry+https://github.com/rust-lang/crates.io-index"
975 | checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
976 | dependencies = [
977 | "proc-macro2",
978 | "quote",
979 | "syn",
980 | ]
981 |
982 | [[package]]
983 | name = "serde_json"
984 | version = "1.0.140"
985 | source = "registry+https://github.com/rust-lang/crates.io-index"
986 | checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
987 | dependencies = [
988 | "indexmap",
989 | "itoa",
990 | "memchr",
991 | "ryu",
992 | "serde",
993 | ]
994 |
995 | [[package]]
996 | name = "serde_spanned"
997 | version = "0.6.8"
998 | source = "registry+https://github.com/rust-lang/crates.io-index"
999 | checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
1000 | dependencies = [
1001 | "serde",
1002 | ]
1003 |
1004 | [[package]]
1005 | name = "shlex"
1006 | version = "1.3.0"
1007 | source = "registry+https://github.com/rust-lang/crates.io-index"
1008 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
1009 |
1010 | [[package]]
1011 | name = "simd-adler32"
1012 | version = "0.3.7"
1013 | source = "registry+https://github.com/rust-lang/crates.io-index"
1014 | checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
1015 |
1016 | [[package]]
1017 | name = "simd_helpers"
1018 | version = "0.1.0"
1019 | source = "registry+https://github.com/rust-lang/crates.io-index"
1020 | checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6"
1021 | dependencies = [
1022 | "quote",
1023 | ]
1024 |
1025 | [[package]]
1026 | name = "smallvec"
1027 | version = "1.15.0"
1028 | source = "registry+https://github.com/rust-lang/crates.io-index"
1029 | checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9"
1030 |
1031 | [[package]]
1032 | name = "strsim"
1033 | version = "0.11.1"
1034 | source = "registry+https://github.com/rust-lang/crates.io-index"
1035 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
1036 |
1037 | [[package]]
1038 | name = "supports-color"
1039 | version = "2.1.0"
1040 | source = "registry+https://github.com/rust-lang/crates.io-index"
1041 | checksum = "d6398cde53adc3c4557306a96ce67b302968513830a77a95b2b17305d9719a89"
1042 | dependencies = [
1043 | "is-terminal",
1044 | "is_ci",
1045 | ]
1046 |
1047 | [[package]]
1048 | name = "supports-color"
1049 | version = "3.0.2"
1050 | source = "registry+https://github.com/rust-lang/crates.io-index"
1051 | checksum = "c64fc7232dd8d2e4ac5ce4ef302b1d81e0b80d055b9d77c7c4f51f6aa4c867d6"
1052 | dependencies = [
1053 | "is_ci",
1054 | ]
1055 |
1056 | [[package]]
1057 | name = "syn"
1058 | version = "2.0.100"
1059 | source = "registry+https://github.com/rust-lang/crates.io-index"
1060 | checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
1061 | dependencies = [
1062 | "proc-macro2",
1063 | "quote",
1064 | "unicode-ident",
1065 | ]
1066 |
1067 | [[package]]
1068 | name = "system-deps"
1069 | version = "6.2.2"
1070 | source = "registry+https://github.com/rust-lang/crates.io-index"
1071 | checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349"
1072 | dependencies = [
1073 | "cfg-expr",
1074 | "heck",
1075 | "pkg-config",
1076 | "toml",
1077 | "version-compare",
1078 | ]
1079 |
1080 | [[package]]
1081 | name = "target-lexicon"
1082 | version = "0.12.16"
1083 | source = "registry+https://github.com/rust-lang/crates.io-index"
1084 | checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
1085 |
1086 | [[package]]
1087 | name = "thiserror"
1088 | version = "1.0.69"
1089 | source = "registry+https://github.com/rust-lang/crates.io-index"
1090 | checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
1091 | dependencies = [
1092 | "thiserror-impl",
1093 | ]
1094 |
1095 | [[package]]
1096 | name = "thiserror-impl"
1097 | version = "1.0.69"
1098 | source = "registry+https://github.com/rust-lang/crates.io-index"
1099 | checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
1100 | dependencies = [
1101 | "proc-macro2",
1102 | "quote",
1103 | "syn",
1104 | ]
1105 |
1106 | [[package]]
1107 | name = "tiff"
1108 | version = "0.9.1"
1109 | source = "registry+https://github.com/rust-lang/crates.io-index"
1110 | checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e"
1111 | dependencies = [
1112 | "flate2",
1113 | "jpeg-decoder",
1114 | "weezl",
1115 | ]
1116 |
1117 | [[package]]
1118 | name = "toml"
1119 | version = "0.8.20"
1120 | source = "registry+https://github.com/rust-lang/crates.io-index"
1121 | checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148"
1122 | dependencies = [
1123 | "serde",
1124 | "serde_spanned",
1125 | "toml_datetime",
1126 | "toml_edit",
1127 | ]
1128 |
1129 | [[package]]
1130 | name = "toml_datetime"
1131 | version = "0.6.8"
1132 | source = "registry+https://github.com/rust-lang/crates.io-index"
1133 | checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
1134 | dependencies = [
1135 | "serde",
1136 | ]
1137 |
1138 | [[package]]
1139 | name = "toml_edit"
1140 | version = "0.22.24"
1141 | source = "registry+https://github.com/rust-lang/crates.io-index"
1142 | checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474"
1143 | dependencies = [
1144 | "indexmap",
1145 | "serde",
1146 | "serde_spanned",
1147 | "toml_datetime",
1148 | "winnow",
1149 | ]
1150 |
1151 | [[package]]
1152 | name = "unicode-ident"
1153 | version = "1.0.18"
1154 | source = "registry+https://github.com/rust-lang/crates.io-index"
1155 | checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
1156 |
1157 | [[package]]
1158 | name = "unicode-width"
1159 | version = "0.2.0"
1160 | source = "registry+https://github.com/rust-lang/crates.io-index"
1161 | checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd"
1162 |
1163 | [[package]]
1164 | name = "utf8parse"
1165 | version = "0.2.2"
1166 | source = "registry+https://github.com/rust-lang/crates.io-index"
1167 | checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
1168 |
1169 | [[package]]
1170 | name = "v_frame"
1171 | version = "0.3.8"
1172 | source = "registry+https://github.com/rust-lang/crates.io-index"
1173 | checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b"
1174 | dependencies = [
1175 | "aligned-vec",
1176 | "num-traits",
1177 | "wasm-bindgen",
1178 | ]
1179 |
1180 | [[package]]
1181 | name = "version-compare"
1182 | version = "0.2.0"
1183 | source = "registry+https://github.com/rust-lang/crates.io-index"
1184 | checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b"
1185 |
1186 | [[package]]
1187 | name = "wasi"
1188 | version = "0.11.0+wasi-snapshot-preview1"
1189 | source = "registry+https://github.com/rust-lang/crates.io-index"
1190 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
1191 |
1192 | [[package]]
1193 | name = "wasi"
1194 | version = "0.14.2+wasi-0.2.4"
1195 | source = "registry+https://github.com/rust-lang/crates.io-index"
1196 | checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
1197 | dependencies = [
1198 | "wit-bindgen-rt",
1199 | ]
1200 |
1201 | [[package]]
1202 | name = "wasm-bindgen"
1203 | version = "0.2.100"
1204 | source = "registry+https://github.com/rust-lang/crates.io-index"
1205 | checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
1206 | dependencies = [
1207 | "cfg-if",
1208 | "once_cell",
1209 | "rustversion",
1210 | "wasm-bindgen-macro",
1211 | ]
1212 |
1213 | [[package]]
1214 | name = "wasm-bindgen-backend"
1215 | version = "0.2.100"
1216 | source = "registry+https://github.com/rust-lang/crates.io-index"
1217 | checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
1218 | dependencies = [
1219 | "bumpalo",
1220 | "log",
1221 | "proc-macro2",
1222 | "quote",
1223 | "syn",
1224 | "wasm-bindgen-shared",
1225 | ]
1226 |
1227 | [[package]]
1228 | name = "wasm-bindgen-macro"
1229 | version = "0.2.100"
1230 | source = "registry+https://github.com/rust-lang/crates.io-index"
1231 | checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
1232 | dependencies = [
1233 | "quote",
1234 | "wasm-bindgen-macro-support",
1235 | ]
1236 |
1237 | [[package]]
1238 | name = "wasm-bindgen-macro-support"
1239 | version = "0.2.100"
1240 | source = "registry+https://github.com/rust-lang/crates.io-index"
1241 | checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
1242 | dependencies = [
1243 | "proc-macro2",
1244 | "quote",
1245 | "syn",
1246 | "wasm-bindgen-backend",
1247 | "wasm-bindgen-shared",
1248 | ]
1249 |
1250 | [[package]]
1251 | name = "wasm-bindgen-shared"
1252 | version = "0.2.100"
1253 | source = "registry+https://github.com/rust-lang/crates.io-index"
1254 | checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
1255 | dependencies = [
1256 | "unicode-ident",
1257 | ]
1258 |
1259 | [[package]]
1260 | name = "web-time"
1261 | version = "1.1.0"
1262 | source = "registry+https://github.com/rust-lang/crates.io-index"
1263 | checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
1264 | dependencies = [
1265 | "js-sys",
1266 | "wasm-bindgen",
1267 | ]
1268 |
1269 | [[package]]
1270 | name = "weezl"
1271 | version = "0.1.8"
1272 | source = "registry+https://github.com/rust-lang/crates.io-index"
1273 | checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082"
1274 |
1275 | [[package]]
1276 | name = "windows-sys"
1277 | version = "0.59.0"
1278 | source = "registry+https://github.com/rust-lang/crates.io-index"
1279 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
1280 | dependencies = [
1281 | "windows-targets",
1282 | ]
1283 |
1284 | [[package]]
1285 | name = "windows-targets"
1286 | version = "0.52.6"
1287 | source = "registry+https://github.com/rust-lang/crates.io-index"
1288 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
1289 | dependencies = [
1290 | "windows_aarch64_gnullvm",
1291 | "windows_aarch64_msvc",
1292 | "windows_i686_gnu",
1293 | "windows_i686_gnullvm",
1294 | "windows_i686_msvc",
1295 | "windows_x86_64_gnu",
1296 | "windows_x86_64_gnullvm",
1297 | "windows_x86_64_msvc",
1298 | ]
1299 |
1300 | [[package]]
1301 | name = "windows_aarch64_gnullvm"
1302 | version = "0.52.6"
1303 | source = "registry+https://github.com/rust-lang/crates.io-index"
1304 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
1305 |
1306 | [[package]]
1307 | name = "windows_aarch64_msvc"
1308 | version = "0.52.6"
1309 | source = "registry+https://github.com/rust-lang/crates.io-index"
1310 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
1311 |
1312 | [[package]]
1313 | name = "windows_i686_gnu"
1314 | version = "0.52.6"
1315 | source = "registry+https://github.com/rust-lang/crates.io-index"
1316 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
1317 |
1318 | [[package]]
1319 | name = "windows_i686_gnullvm"
1320 | version = "0.52.6"
1321 | source = "registry+https://github.com/rust-lang/crates.io-index"
1322 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
1323 |
1324 | [[package]]
1325 | name = "windows_i686_msvc"
1326 | version = "0.52.6"
1327 | source = "registry+https://github.com/rust-lang/crates.io-index"
1328 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
1329 |
1330 | [[package]]
1331 | name = "windows_x86_64_gnu"
1332 | version = "0.52.6"
1333 | source = "registry+https://github.com/rust-lang/crates.io-index"
1334 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
1335 |
1336 | [[package]]
1337 | name = "windows_x86_64_gnullvm"
1338 | version = "0.52.6"
1339 | source = "registry+https://github.com/rust-lang/crates.io-index"
1340 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
1341 |
1342 | [[package]]
1343 | name = "windows_x86_64_msvc"
1344 | version = "0.52.6"
1345 | source = "registry+https://github.com/rust-lang/crates.io-index"
1346 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
1347 |
1348 | [[package]]
1349 | name = "winnow"
1350 | version = "0.7.6"
1351 | source = "registry+https://github.com/rust-lang/crates.io-index"
1352 | checksum = "63d3fcd9bba44b03821e7d699eeee959f3126dcc4aa8e4ae18ec617c2a5cea10"
1353 | dependencies = [
1354 | "memchr",
1355 | ]
1356 |
1357 | [[package]]
1358 | name = "wit-bindgen-rt"
1359 | version = "0.39.0"
1360 | source = "registry+https://github.com/rust-lang/crates.io-index"
1361 | checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
1362 | dependencies = [
1363 | "bitflags 2.9.0",
1364 | ]
1365 |
1366 | [[package]]
1367 | name = "zerocopy"
1368 | version = "0.8.24"
1369 | source = "registry+https://github.com/rust-lang/crates.io-index"
1370 | checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879"
1371 | dependencies = [
1372 | "zerocopy-derive",
1373 | ]
1374 |
1375 | [[package]]
1376 | name = "zerocopy-derive"
1377 | version = "0.8.24"
1378 | source = "registry+https://github.com/rust-lang/crates.io-index"
1379 | checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be"
1380 | dependencies = [
1381 | "proc-macro2",
1382 | "quote",
1383 | "syn",
1384 | ]
1385 |
1386 | [[package]]
1387 | name = "zune-core"
1388 | version = "0.4.12"
1389 | source = "registry+https://github.com/rust-lang/crates.io-index"
1390 | checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"
1391 |
1392 | [[package]]
1393 | name = "zune-inflate"
1394 | version = "0.2.54"
1395 | source = "registry+https://github.com/rust-lang/crates.io-index"
1396 | checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02"
1397 | dependencies = [
1398 | "simd-adler32",
1399 | ]
1400 |
1401 | [[package]]
1402 | name = "zune-jpeg"
1403 | version = "0.4.14"
1404 | source = "registry+https://github.com/rust-lang/crates.io-index"
1405 | checksum = "99a5bab8d7dedf81405c4bb1f2b83ea057643d9cb28778cea9eecddeedd2e028"
1406 | dependencies = [
1407 | "zune-core",
1408 | ]
1409 |
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "dipc"
3 | version = "1.0.0"
4 | edition = "2021"
5 | description = "Convert your favorite images and wallpapers with your favorite color palettes/themes"
6 | homepage = "https://github.com/doprz/dipc"
7 | repository = "https://github.com/doprz/dipc"
8 | readme = "README.md"
9 | license = "MIT OR Apache-2.0"
10 | keywords = ["cli", "graphics", "utility", "image", "tool"]
11 | categories = [
12 | "command-line-interface",
13 | "command-line-utilities",
14 | "graphics",
15 | "multimedia::images",
16 | "rendering",
17 | ]
18 |
19 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
20 |
21 | [dependencies]
22 | clap = { version = "4.5", features = ["derive"] }
23 | serde_json = { version = "1.0", features = ["preserve_order"] }
24 | image = { version = "0.25" }
25 | deltae = "0.3"
26 | lab = "0.11"
27 | owo-colors = { version = "4.2", features = ["supports-colors"] }
28 | supports-color = "3.0"
29 | rayon = "1.10"
30 | indicatif = { version = "0.17", features = ["rayon"] }
31 |
--------------------------------------------------------------------------------
/LICENSE-APACHE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/LICENSE-MIT:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 doprz
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 | # dipc
2 |
3 | [](https://crates.io/crates/dipc)
4 | [](https://formulae.brew.sh/formula/dipc)
5 |
6 |
7 |
8 |
9 |
10 |
11 | doprz' image palette converter
12 |
13 | Convert your favorite images and wallpapers with your favorite color palettes/themes
14 |
15 | ## Color Palettes/Themes
16 |
17 | - catppuccin
18 | - dracula
19 | - edge
20 | - everforest
21 | - gruvbox
22 | - gruvbox-material
23 | - nord
24 | - onedark
25 | - rose-pine
26 | - solarized
27 | - tokyo-night
28 |
29 | ## Examples
30 |
31 | 
32 |
33 | ### Image Credits
34 |
35 | Paul Bill - [https://unsplash.com/@hoffman11](https://unsplash.com/@hoffman11)
36 |
37 | Adrien Vajas - [https://unsplash.com/@adrien_vj](https://unsplash.com/@adrien_vj)
38 |
39 | Filipp Romanovski - [https://unsplash.com/@filipp_roman_photography](https://unsplash.com/@filipp_roman_photography)
40 |
41 | ## Installation
42 |
43 | ### Homebrew
44 |
45 | ```sh
46 | brew install dipc
47 | ```
48 |
49 | ### Cargo
50 |
51 | ```sh
52 | cargo install dipc
53 | ```
54 |
55 | ### From Source
56 |
57 | To build and install from source, first checkout the tag or branch you want to install, then run
58 |
59 | ```sh
60 | cargo install --path .
61 | ```
62 |
63 | This will build and install `dipc` in your `~/.cargo/bin`. Make sure that `~/.cargo/bin` is in your `$PATH` variable.
64 |
65 | ## Usage
66 |
67 | ```
68 | Convert your favorite images and wallpapers with your favorite color palettes/themes
69 |
70 | Usage: dipc [OPTIONS] [FILE]...
71 |
72 | Arguments:
73 |
74 | The color palette to use:
75 | - name of a builtin theme
76 | - path to a theme in JSON
77 | - a JSON string with the theme (starting with `JSON: {}`)
78 | Run with --help instead of -h for a list of all builtin themes
79 |
80 | Builtin themes:
81 | - catppuccin
82 | - dracula
83 | - edge
84 | - everforest
85 | - gruvbox
86 | - gruvbox-material
87 | - nord
88 | - onedark
89 | - rose-pine
90 | - solarized
91 | - tokyo-night
92 |
93 | [FILE]...
94 | The image(s) to process
95 |
96 | Options:
97 | -s, --styles
98 | The color palette variation(s) to use
99 | Run with --help instead of -h for a list of all possible values
100 |
101 | Possible values:
102 | - `all` to generate an image for each of the variations
103 | - `none` if you are using a flat theme without variations
104 | - or a comma-delimited list of the names of variations it should use
105 |
106 | [default: all]
107 |
108 | -o, --output
109 | Output image(s) name/path as a comma-delimited list
110 |
111 | -d, --dir-output
112 | Output directory name/path
113 |
114 | -m, --method
115 | CIELAB DeltaE method to use
116 |
117 | [default: de2000]
118 |
119 | Possible values:
120 | - de2000: The default DeltaE method
121 | - de1994g: CIE94 DeltaE implementation, weighted with a tolerance for graphics
122 | - de1994t: CIE94 DeltaE implementation, weighted with a tolerance for textiles
123 | - de1976: The original DeltaE implementation, a basic euclidian distance formula
124 |
125 | -v, --verbose...
126 | Verbose mode (-v, -vv, -vvv)
127 |
128 | -h, --help
129 | Print help (see a summary with '-h')
130 |
131 | -V, --version
132 | Print version
133 | ```
134 |
135 | ### Convert all images in directory
136 |
137 | ```sh
138 | # Save to current directory
139 | dipc /*
140 |
141 | # Save to output directory
142 | dipc --dir-output /*
143 | ```
144 |
145 | ### Convert multiple images
146 |
147 | ```sh
148 | dipc img0.png img1.png
149 |
150 | # Rename files
151 | dipc --output new-img0.png,new-img1.png img0.png img1.png
152 | ```
153 |
154 | ### Color palette variation(s)/style(s)
155 |
156 | ```sh
157 | dipc --styles Style0 img.png
158 | dipc --styles Style0,Style1 img.png
159 | ```
160 |
161 | ### CIELAB DeltaE method
162 |
163 | ```sh
164 | dipc --method img.png
165 | ```
166 |
167 | ## License
168 |
169 | `dipc` is dual-licensed under the terms of both the MIT License and the Apache License 2.0
170 |
171 | SPDX-License-Identifier: MIT OR Apache-2.0
172 |
--------------------------------------------------------------------------------
/flake.lock:
--------------------------------------------------------------------------------
1 | {
2 | "nodes": {
3 | "flake-utils": {
4 | "inputs": {
5 | "systems": "systems"
6 | },
7 | "locked": {
8 | "lastModified": 1689068808,
9 | "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=",
10 | "owner": "numtide",
11 | "repo": "flake-utils",
12 | "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4",
13 | "type": "github"
14 | },
15 | "original": {
16 | "owner": "numtide",
17 | "repo": "flake-utils",
18 | "type": "github"
19 | }
20 | },
21 | "naersk": {
22 | "inputs": {
23 | "nixpkgs": "nixpkgs"
24 | },
25 | "locked": {
26 | "lastModified": 1690373729,
27 | "narHash": "sha256-e136hTT7LqQ2QjOTZQMW+jnsevWwBpMj78u6FRUsH9I=",
28 | "owner": "nix-community",
29 | "repo": "naersk",
30 | "rev": "d9a33d69a9c421d64c8d925428864e93be895dcc",
31 | "type": "github"
32 | },
33 | "original": {
34 | "owner": "nix-community",
35 | "repo": "naersk",
36 | "type": "github"
37 | }
38 | },
39 | "nixpkgs": {
40 | "locked": {
41 | "lastModified": 1691368598,
42 | "narHash": "sha256-ia7li22keBBbj02tEdqjVeLtc7ZlSBuhUk+7XTUFr14=",
43 | "path": "/nix/store/631cgbs310h1rcix7zs171xzx7p2y97g-source",
44 | "rev": "5a8e9243812ba528000995b294292d3b5e120947",
45 | "type": "path"
46 | },
47 | "original": {
48 | "id": "nixpkgs",
49 | "type": "indirect"
50 | }
51 | },
52 | "nixpkgs_2": {
53 | "locked": {
54 | "lastModified": 1691371061,
55 | "narHash": "sha256-BxPbPVlBIoneaXIBiHd0LVzA+L4nmvFCNBU6TmQAiMM=",
56 | "owner": "NixOS",
57 | "repo": "nixpkgs",
58 | "rev": "5068bc8fe943bde3c446326da8d0ca9c93d5a682",
59 | "type": "github"
60 | },
61 | "original": {
62 | "owner": "NixOS",
63 | "ref": "nixpkgs-unstable",
64 | "repo": "nixpkgs",
65 | "type": "github"
66 | }
67 | },
68 | "root": {
69 | "inputs": {
70 | "flake-utils": "flake-utils",
71 | "naersk": "naersk",
72 | "nixpkgs": "nixpkgs_2"
73 | }
74 | },
75 | "systems": {
76 | "locked": {
77 | "lastModified": 1681028828,
78 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
79 | "owner": "nix-systems",
80 | "repo": "default",
81 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
82 | "type": "github"
83 | },
84 | "original": {
85 | "owner": "nix-systems",
86 | "repo": "default",
87 | "type": "github"
88 | }
89 | }
90 | },
91 | "root": "root",
92 | "version": 7
93 | }
94 |
--------------------------------------------------------------------------------
/flake.nix:
--------------------------------------------------------------------------------
1 | {
2 | inputs = {
3 | flake-utils.url = "github:numtide/flake-utils";
4 | naersk.url = "github:nix-community/naersk";
5 | nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
6 | };
7 |
8 | outputs = { self, flake-utils, naersk, nixpkgs, ... }:
9 | flake-utils.lib.eachDefaultSystem (system:
10 | let
11 | pkgs = (import nixpkgs) {
12 | inherit system;
13 | };
14 |
15 | naersk' = pkgs.callPackage naersk {};
16 |
17 | in rec {
18 | # For `nix build` & `nix run`:
19 | packages.default = naersk'.buildPackage {
20 | src = ./.;
21 | };
22 |
23 | # For `nix develop` (optional, can be skipped):
24 | devShell = pkgs.mkShell {
25 | nativeBuildInputs = with pkgs; [ rustc cargo ];
26 | };
27 | }
28 | );
29 | }
30 |
--------------------------------------------------------------------------------
/images/dipc_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doprz/dipc/a046ef2f25cb4a1747c6425e2f4f4cad3658688d/images/dipc_dark.png
--------------------------------------------------------------------------------
/images/dipc_examples.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doprz/dipc/a046ef2f25cb4a1747c6425e2f4f4cad3658688d/images/dipc_examples.png
--------------------------------------------------------------------------------
/images/dipc_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doprz/dipc/a046ef2f25cb4a1747c6425e2f4f4cad3658688d/images/dipc_light.png
--------------------------------------------------------------------------------
/src/cli.rs:
--------------------------------------------------------------------------------
1 | use std::{fs::File, io::BufReader, path::PathBuf, str::FromStr};
2 |
3 | use clap::Parser;
4 | use serde_json::Value;
5 |
6 | use crate::delta::CLIDEMethod;
7 |
8 | #[derive(Parser, Debug)]
9 | #[command(author, version, about, long_about = None)]
10 | pub struct Cli {
11 | // Options
12 | /// The color palette variation(s) to use
13 | /// Run with --help instead of -h for a list of all possible values
14 | ///
15 | /// Possible values:
16 | /// - `all` to generate an image for each of the variations
17 | /// - `none` if you are using a flat theme without variations
18 | /// - or a comma-delimited list of the names of variations it should use
19 | #[arg(
20 | short,
21 | long,
22 | value_name = "VARIATIONS",
23 | default_value = "all",
24 | verbatim_doc_comment
25 | )]
26 | pub styles: ColorPaletteStyles,
27 |
28 | /// Output image(s) name/path as a comma-delimited list
29 | #[arg(short, long, value_name = "PATH", value_delimiter = ',')]
30 | pub output: Option>,
31 |
32 | /// Output directory name/path
33 | #[arg(short, long, value_name = "PATH")]
34 | pub dir_output: Option,
35 |
36 | /// CIELAB DeltaE method to use
37 | #[arg(short, long, value_enum, default_value = "de2000")]
38 | pub method: CLIDEMethod,
39 |
40 | /// Verbose mode (-v, -vv, -vvv)
41 | #[arg(short, long, action = clap::ArgAction::Count)]
42 | pub verbose: u8,
43 |
44 | // Arguments
45 | /// The color palette to use:
46 | /// - name of a builtin theme
47 | /// - path to a theme in JSON
48 | /// - a JSON string with the theme (starting with `JSON: {}`)
49 | /// Run with --help instead of -h for a list of all builtin themes
50 | ///
51 | /// Builtin themes:
52 | /// - catppuccin
53 | /// - dracula
54 | /// - edge
55 | /// - everforest
56 | /// - gruvbox
57 | /// - gruvbox-material
58 | /// - nord
59 | /// - onedark
60 | /// - rose-pine
61 | /// - solarized
62 | /// - tokyo-night
63 | #[arg(value_name = "PALETTE", verbatim_doc_comment)]
64 | pub color_palette: ColorPalette,
65 |
66 | /// The image(s) to process
67 | #[arg(value_name = "FILE", value_delimiter = ',')]
68 | pub process: Vec,
69 | }
70 |
71 | #[derive(Clone, Debug)]
72 | pub enum ColorPaletteStyles {
73 | All,
74 | Some { styles: Vec },
75 | None,
76 | }
77 |
78 | impl FromStr for ColorPaletteStyles {
79 | type Err = String;
80 |
81 | fn from_str(s: &str) -> Result {
82 | let style = match s {
83 | "all" | "ALL" => Self::All,
84 | "none" | "NONE" | "no" | "NO" => Self::None,
85 | some => Self::Some {
86 | styles: {
87 | let mut vars = Vec::new();
88 | for var in some.split(',') {
89 | if var.is_empty() {
90 | return Err("One of the variations seems to be an empty string. Do you have a double comma in your variations list (-v)?".to_string());
91 | };
92 | vars.push(var.to_string())
93 | }
94 | if vars.is_empty() {
95 | return Err("No styles selected".to_string());
96 | };
97 | vars
98 | },
99 | },
100 | };
101 | Ok(style)
102 | }
103 | }
104 |
105 | #[derive(Clone, Debug)]
106 | pub enum ColorPalette {
107 | RawJSON { map: serde_json::Map },
108 | Catppuccin,
109 | Dracula,
110 | Edge,
111 | Everforest,
112 | Gruvbox,
113 | GruvboxMaterial,
114 | Nord,
115 | OneDark,
116 | RosePine,
117 | Solarized,
118 | TokyoNight,
119 | }
120 |
121 | impl std::fmt::Display for ColorPalette {
122 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
123 | match self {
124 | ColorPalette::RawJSON { map } => {
125 | write!(f, "JSON: {}", serde_json::to_string(map).unwrap())
126 | }
127 | ColorPalette::Catppuccin => write!(f, "catppuccin"),
128 | ColorPalette::Dracula => write!(f, "dracula"),
129 | ColorPalette::Edge => write!(f, "edge"),
130 | ColorPalette::Everforest => write!(f, "everforest"),
131 | ColorPalette::Gruvbox => write!(f, "gruvbox"),
132 | ColorPalette::GruvboxMaterial => write!(f, "gruvbox-material"),
133 | ColorPalette::Nord => write!(f, "nord"),
134 | ColorPalette::OneDark => write!(f, "onedark"),
135 | ColorPalette::RosePine => write!(f, "rose-pine"),
136 | ColorPalette::Solarized => write!(f, "solarized"),
137 | ColorPalette::TokyoNight => write!(f, "tokyo-night"),
138 | }
139 | }
140 | }
141 |
142 | impl FromStr for ColorPalette {
143 | type Err = String;
144 |
145 | fn from_str(s: &str) -> Result {
146 | if s.starts_with("JSON: ") {
147 | let jsonstr = &s[5..];
148 | let json: Value = serde_json::from_str(jsonstr).map_err(|err| err.to_string())?;
149 | let Value::Object(map) = json else {
150 | return Err("Encountered error while parsing inline JSON string: the string appears to not be a JSON object".to_string());
151 | };
152 | return Ok(ColorPalette::RawJSON { map });
153 | };
154 |
155 | let palette = match s {
156 | "catppuccin" => ColorPalette::Catppuccin,
157 | "dracula" => ColorPalette::Dracula,
158 | "edge" => ColorPalette::Edge,
159 | "everforest" => ColorPalette::Everforest,
160 | "gruvbox" => ColorPalette::Gruvbox,
161 | "gruvbox-material" | "gruvbox_material" | "gruvboxmaterial" => {
162 | ColorPalette::GruvboxMaterial
163 | }
164 | "nord" => ColorPalette::Nord,
165 | "onedark" | "one_dark" | "one-dark" => ColorPalette::OneDark,
166 | "rose-pine" | "rose_pine" | "rosepine" => ColorPalette::RosePine,
167 | "solarized" => ColorPalette::Solarized,
168 | "tokyo-night" | "tokyo_night" | "tokyonight" => ColorPalette::TokyoNight,
169 |
170 | // The color palette seems to be the path to an external file
171 | external => {
172 | let external: PathBuf = external.into();
173 | if !external.is_file() {
174 | return Err(format!("Theme source file `{s}` appears to not be a file."));
175 | };
176 | let file = File::open(external).map_err(|err| err.to_string())?;
177 | let file = BufReader::new(file);
178 | let json = serde_json::from_reader(file)
179 | .map_err(|err| format!("Error while parsing JSON content of {s}: {err}"))?;
180 | let Value::Object(map) = json else {
181 | return Err("Encountered error while parsing JSON theme file: the contents of the file are valid JSON but do not appear to be a JSON object".to_string());
182 | };
183 | ColorPalette::RawJSON { map }
184 | }
185 | };
186 | Ok(palette)
187 | }
188 | }
189 |
--------------------------------------------------------------------------------
/src/config.rs:
--------------------------------------------------------------------------------
1 | use std::path::Path;
2 | use std::path::PathBuf;
3 |
4 | use image::Rgb;
5 | use serde_json::Value;
6 |
7 | use crate::cli::{ColorPalette, ColorPaletteStyles};
8 |
9 | pub fn parse_palette(
10 | json: serde_json::Map,
11 | styles: &ColorPaletteStyles,
12 | ) -> Result, String> {
13 | match styles {
14 | ColorPaletteStyles::None => {
15 | // Flat theme
16 | Ok(vec![Palette::try_from(json)?])
17 | }
18 | ColorPaletteStyles::All => {
19 | // Parse all styles
20 | let mut out = Vec::with_capacity(json.len());
21 | for (style, val) in json {
22 | let Value::Object(map) = val else {
23 | return Err(format!("Failed to parse palette style `{style}`: It's value is not a JSON object"))
24 | };
25 | let mut palette = Palette::try_from(map)
26 | .map_err(|err| format!("Failed to parse palette style `{style}`: {err}"))?;
27 | palette.name = Some(style);
28 | out.push(palette);
29 | }
30 | Ok(out)
31 | }
32 | ColorPaletteStyles::Some { styles } => {
33 | let mut json = json;
34 | let mut out = Vec::with_capacity(styles.len());
35 | for style in styles {
36 | let Some(Value::Object(map)) = json.remove(style) else {
37 | return Err(format!("Failed to parse palette style `{style}`: It does not exist in the theme JSON source"))
38 | };
39 | let mut palette = Palette::try_from(map)
40 | .map_err(|err| format!("Failed to parse palette style `{style}`: {err}"))?;
41 | palette.name = Some(style.to_string());
42 | out.push(palette);
43 | }
44 | Ok(out)
45 | }
46 | }
47 | }
48 |
49 | #[derive(Debug, Clone)]
50 | pub struct Palette {
51 | pub name: Option,
52 | pub colors: Vec<(String, Rgb)>,
53 | }
54 |
55 | impl TryFrom> for Palette {
56 | type Error = String;
57 |
58 | fn try_from(json: serde_json::Map) -> Result {
59 | let mut colors = Vec::with_capacity(json.len());
60 | for (name, value) in json {
61 | let mut colorarr: [u8; 3] = [0_u8; 3];
62 | match value {
63 | Value::String(hex) => {
64 | // For representing a color as a hex string `#FF8800` in JSON
65 | if !hex.starts_with('#') {
66 | return Err(format!(
67 | "Encountered a color string not in the `#HEX` format: `{hex}`"
68 | ));
69 | };
70 | let color = &hex[1..];
71 | if !matches!(color.len(), 3 | 6) {
72 | return Err(format!(
73 | "Encountered a HEX color string of an invalid length: `{hex}`"
74 | ));
75 | }
76 | let channel_length = color.len() / 3;
77 | let multiplier = match channel_length {
78 | 1 => 16,
79 | 2 => 1,
80 | _ => unreachable!(),
81 | };
82 | for (channel, c) in colorarr.iter_mut().enumerate() {
83 | let start = channel * channel_length;
84 | let Some(channelstr) = color.get(start..start + channel_length) else {
85 | return Err(format!(
86 | "Failed to parse HEX color string `{hex}`. Does it contain a multi-byte sequence? Only hexadecimal digits are allowed."
87 | ));
88 | };
89 | let Ok(val) = u8::from_str_radix(channelstr, 16).map(|x| x * multiplier) else {
90 | return Err(format!(
91 | "Failed to parse HEX color string `{hex}`. Only hexadecimal digits are allowed."
92 | ));
93 | };
94 | *c = val;
95 | }
96 | }
97 | Value::Array(arr) => {
98 | // For representing a color as `[128, 255, 0]` in JSON
99 | if arr.len() != 3 {
100 | return Err(format!(
101 | "Encountered a color array with {} elements instead of 3: {arr:?}",
102 | arr.len()
103 | ));
104 | }
105 | for (i, channel) in arr.iter().enumerate() {
106 | let Value::Number(num) = channel else {
107 | return Err(format!("Encountered a non-number in a color array: {arr:?}"))
108 | };
109 | let Some(Ok(brightness)): Option> = num.as_u64().map(|num| num.try_into()) else {
110 | return Err(format!("Encountered a number not representable by an 8-bit-integer in a color array: {arr:?}, element {i}"))
111 | };
112 | colorarr[i] = brightness
113 | }
114 | }
115 | Value::Object(mut map) => {
116 | // For representing a color as a JSON object: `{"r": 255, "g": 128, "b": 0}`
117 | for (channel, name) in ["r", "g", "b"].into_iter().enumerate() {
118 | let Some(obj)=map.remove(name) else {
119 | return Err(format!(r#"Key `{name}` not found in JSON object {map:?}. The format is `{{"r": 255, "g": 128, "b": 0\}}"#))
120 | };
121 | let Value::Number(num) = obj else {
122 | return Err(format!(r#"Key `{name}` has a non-number value in JSON object {map:?}. The format is `{{"r": 255, "g": 128, "b": 0}}"#))
123 | };
124 | let Some(Ok(brightness)): Option> = num.as_u64().map(|num| num.try_into()) else {
125 | return Err(format!("Encountered a number not representable by an 8-bit-integer in a color object: at key {name}: {num}"))
126 | };
127 | colorarr[channel] = brightness;
128 | }
129 | }
130 | _ => {}
131 | };
132 | colors.push((name, Rgb(colorarr)))
133 | }
134 | Ok(Palette { colors, name: None })
135 | }
136 | }
137 |
138 | pub fn output_file_name(
139 | dir_path: &Option,
140 | input_path: &Path,
141 | color_palette: &ColorPalette,
142 | color_palette_variations: &[Palette],
143 | method: deltae::DEMethod,
144 | ) -> PathBuf {
145 | let mut output = PathBuf::new();
146 | let mut output_file_name = String::new();
147 |
148 | if let Some(dir) = dir_path {
149 | match dir.to_str() {
150 | Some(dir) => output.push(dir),
151 | None => {
152 | eprintln!("Failed to convert directory path to string");
153 | std::process::exit(1);
154 | }
155 | };
156 | }
157 |
158 | let file_stem = match input_path.file_stem() {
159 | Some(stem) => match stem.to_str() {
160 | Some(stem) => stem,
161 | None => {
162 | eprintln!("Failed to convert file stem to string");
163 | eprintln!("Defaulting to \"image\"");
164 | "image"
165 | }
166 | },
167 | None => {
168 | eprintln!("Failed to get file stem");
169 | eprintln!("Defaulting to \"image\"");
170 | "image"
171 | }
172 | };
173 | output_file_name.push_str(file_stem);
174 |
175 | let color_palette: String = match &color_palette {
176 | ColorPalette::RawJSON { .. } => String::from("custom"),
177 | _ => format!("{}", color_palette),
178 | };
179 | output_file_name.push_str(format!("_{}", color_palette).as_str());
180 |
181 | color_palette_variations.iter().for_each(|variation| {
182 | if let Some(name) = &variation.name {
183 | output_file_name.push_str(format!("-{}", name.replace(' ', "_")).as_str());
184 | }
185 | });
186 |
187 | if method != deltae::DEMethod::DE2000 {
188 | output_file_name.push_str(format!("_{}", method).as_str());
189 | }
190 |
191 | output.push(output_file_name);
192 | output.set_extension("png");
193 | output
194 | }
195 |
--------------------------------------------------------------------------------
/src/delta.rs:
--------------------------------------------------------------------------------
1 | use deltae::LabValue;
2 |
3 | #[derive(Debug, Clone, Copy)]
4 | pub struct Lab {
5 | l: f32,
6 | a: f32,
7 | b: f32,
8 | }
9 |
10 | impl From<[u8; 3]> for Lab {
11 | fn from(value: [u8; 3]) -> Self {
12 | let lab::Lab { l, a, b } = lab::Lab::from_rgb(&value);
13 | Lab { l, a, b }
14 | }
15 | }
16 |
17 | impl From<[u8; 4]> for Lab {
18 | fn from(value: [u8; 4]) -> Self {
19 | let lab::Lab { l, a, b } = lab::Lab::from_rgba(&value);
20 | Lab { l, a, b }
21 | }
22 | }
23 |
24 | impl From for LabValue {
25 | fn from(lab: Lab) -> Self {
26 | LabValue {
27 | l: lab.l,
28 | a: lab.a,
29 | b: lab.b,
30 | }
31 | }
32 | }
33 |
34 | impl Lab {
35 | pub fn to_nearest_palette(self, palette: &[Lab], method: deltae::DEMethod) -> Self {
36 | let mut min_distance = std::f32::MAX;
37 | let mut new_color = self;
38 |
39 | for &color in palette {
40 | // let delta = *deltae::DeltaE::new(self, color, deltae::DEMethod::DE2000).value();
41 | let delta = *deltae::DeltaE::new(self, color, method).value();
42 |
43 | if delta < min_distance {
44 | min_distance = delta;
45 | new_color = color;
46 | }
47 | }
48 |
49 | new_color
50 | }
51 |
52 | pub fn to_rgb(self) -> [u8; 3] {
53 | let lab = lab::Lab {
54 | l: self.l,
55 | a: self.a,
56 | b: self.b,
57 | };
58 | lab.to_rgb()
59 | }
60 | }
61 |
62 | // Implement DeltaEq for Lab
63 | impl deltae::DeltaEq for Lab {}
64 |
65 | #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, clap::ValueEnum)]
66 | pub enum CLIDEMethod {
67 | /// The default DeltaE method
68 | DE2000,
69 | // /// An implementation of DeltaE with separate tolerances for Lightness and Chroma
70 | // DECMC(
71 | // /// Lightness tolerance
72 | // f32,
73 | // /// Chroma tolerance
74 | // f32,
75 | // ),
76 | /// CIE94 DeltaE implementation, weighted with a tolerance for graphics
77 | DE1994G,
78 | /// CIE94 DeltaE implementation, weighted with a tolerance for textiles
79 | DE1994T,
80 | /// The original DeltaE implementation, a basic euclidian distance formula
81 | DE1976,
82 | }
83 |
84 | impl Default for CLIDEMethod {
85 | fn default() -> Self {
86 | Self::DE2000
87 | }
88 | }
89 |
90 | impl std::fmt::Display for CLIDEMethod {
91 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
92 | match self {
93 | CLIDEMethod::DE2000 => write!(f, "de2000"),
94 | // CLIDEMethod::DECMC(l, c) => write!(f, "decmc({}, {})", l, c),
95 | CLIDEMethod::DE1994G => write!(f, "de1994g"),
96 | CLIDEMethod::DE1994T => write!(f, "de1994t"),
97 | CLIDEMethod::DE1976 => write!(f, "de1976"),
98 | }
99 | }
100 | }
101 |
102 | impl From for deltae::DEMethod {
103 | fn from(method: CLIDEMethod) -> Self {
104 | match method {
105 | CLIDEMethod::DE2000 => Self::DE2000,
106 | // CLIDEMethod::DECMC(l, c) => Self::DECMC(l, c),
107 | CLIDEMethod::DE1994G => Self::DE1994G,
108 | CLIDEMethod::DE1994T => Self::DE1994T,
109 | CLIDEMethod::DE1976 => Self::DE1976,
110 | }
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/src/main.rs:
--------------------------------------------------------------------------------
1 | use std::io::{self, stdout, BufWriter, Write};
2 |
3 | use clap::Parser;
4 | use delta::Lab;
5 | use indicatif::{ParallelProgressIterator, ProgressBar, ProgressStyle};
6 | use owo_colors::{OwoColorize, Style};
7 | use rayon::{
8 | prelude::{IntoParallelRefIterator, ParallelIterator},
9 | slice::ParallelSliceMut,
10 | };
11 |
12 | use crate::{
13 | cli::Cli,
14 | config::{output_file_name, parse_palette},
15 | };
16 |
17 | mod cli;
18 | mod config;
19 | mod delta;
20 | mod palettes;
21 |
22 | fn main() -> io::Result<()> {
23 | let total_start = std::time::Instant::now();
24 | let cli = Cli::parse();
25 |
26 | let stdout = stdout().lock();
27 | let mut writer = BufWriter::new(stdout);
28 |
29 | if cli.process.is_empty() {
30 | eprintln!(
31 | "{}",
32 | "You need to provide at least a single image to process"
33 | .if_supports_color(owo_colors::Stream::Stderr, |text| text.red())
34 | );
35 | std::process::exit(127)
36 | };
37 | if let Some(output_vec) = &cli.output {
38 | if output_vec.is_empty() {
39 | eprintln!(
40 | "{}",
41 | "You need to provide at least a single output image name or path"
42 | .if_supports_color(owo_colors::Stream::Stderr, |text| text.red())
43 | );
44 | }
45 | }
46 | match &cli.output {
47 | Some(output_vec) if output_vec.len() != cli.process.len() => {
48 | eprintln!(
49 | "{}",
50 | "You need to provide the same amount of output image names/paths as input images"
51 | .if_supports_color(owo_colors::Stream::Stderr, |text| text.red())
52 | );
53 | std::process::exit(127)
54 | }
55 | _ => {}
56 | }
57 |
58 | println!(
59 | "Color palette: {}\nStyles: {:?}\nDeltaE method: {}",
60 | cli.color_palette, cli.styles, cli.method
61 | );
62 | match &cli.dir_output {
63 | Some(path) if !path.is_dir() => {
64 | eprintln!(
65 | "Output directory \"{}\" does not exist.\nAttempting to create it.",
66 | path.display()
67 | );
68 | if let Err(err) = std::fs::create_dir_all(path) {
69 | eprintln!(
70 | "Creating provided output directory failed with error: {}",
71 | err.if_supports_color(owo_colors::Stream::Stderr, |text| text.red())
72 | );
73 | std::process::exit(127)
74 | };
75 | }
76 | _ => {}
77 | }
78 | if let Some(path) = &cli.dir_output {
79 | println!("Writing results to {:#?} directory.", path);
80 | }
81 | println!("Processing {:#?}", &cli.process);
82 | if let Some(output_vec) = &cli.output {
83 | println!("Output names: {:#?}", output_vec);
84 | }
85 |
86 | let mut palettes = match parse_palette(cli.color_palette.clone().get_json(), &cli.styles) {
87 | Ok(p) => p,
88 | Err(err) => {
89 | eprintln!(
90 | "{}",
91 | err.if_supports_color(owo_colors::Stream::Stderr, |text| text.red())
92 | );
93 | std::process::exit(127)
94 | }
95 | };
96 | // Print palettes
97 | let color = match supports_color::on_cached(supports_color::Stream::Stdout) {
98 | Some(level) => level.has_16m,
99 | None => false,
100 | };
101 | let max_name = palettes
102 | .iter()
103 | .map(|p| p.name.as_ref().map(|n| n.len()).unwrap_or_default())
104 | .max()
105 | .unwrap_or_default();
106 | for palette in &palettes {
107 | if let Some(name) = &palette.name {
108 | writeln!(
109 | writer,
110 | "{: = palettes
141 | .par_iter()
142 | .flat_map_iter(|palette| {
143 | palette
144 | .colors
145 | .iter()
146 | .map(|(_name, color)| Lab::from(color.0))
147 | })
148 | .collect();
149 |
150 | for (idx, path) in cli.process.iter().enumerate() {
151 | let start = std::time::Instant::now();
152 | // Open image
153 | let mut image = match image::open(path) {
154 | Ok(i) => i.into_rgba8(),
155 | Err(err) => {
156 | eprintln!(
157 | "Encountered error while opening image at path {}: {}",
158 | path.display()
159 | .if_supports_color(owo_colors::Stream::Stderr, |text| text.blue()),
160 | err.if_supports_color(owo_colors::Stream::Stderr, |text| text.red())
161 | );
162 | std::process::exit(127)
163 | }
164 | };
165 |
166 | println!(
167 | "[{}/{}] Converting image... (this may take a while)",
168 | idx + 1,
169 | cli.process.len()
170 | );
171 |
172 | const PIXEL_SIZE: usize = 4;
173 | const CHUNK: usize = 4096;
174 |
175 | // Apply palettes to image
176 | let progress_bar = ProgressBar::new(
177 | (image.len() / CHUNK)
178 | .try_into()
179 | .expect("Failed to convert usize to u64"),
180 | );
181 | progress_bar.set_style(
182 | ProgressStyle::with_template(
183 | "[{elapsed_precise}] [{wide_bar}] {pos}/{len} ({eta_precise})",
184 | )
185 | .expect("Failed to set progress bar style"),
186 | );
187 | let progress_bar_clone = progress_bar.clone();
188 | image
189 | .par_chunks_mut(CHUNK)
190 | .progress_with(progress_bar)
191 | .for_each(|chunk| {
192 | chunk.chunks_exact_mut(PIXEL_SIZE).for_each(|bytes| {
193 | let pixel: &mut [u8; 3] = &mut bytes[..3].try_into().unwrap();
194 | let lab = Lab::from(*pixel);
195 | let new_rgb = lab
196 | .to_nearest_palette(&palettes_lab, deltae::DEMethod::from(cli.method))
197 | .to_rgb();
198 | *pixel = new_rgb;
199 | });
200 | });
201 | progress_bar_clone.finish();
202 |
203 | let output_file_name = match &cli.output {
204 | Some(output_vec) => {
205 | let mut name = output_vec[idx].clone();
206 | name.set_extension("png");
207 | match &cli.dir_output {
208 | Some(path) => {
209 | let mut output = path.clone();
210 | output.push(name);
211 | output
212 | }
213 | None => {
214 | let mut output = std::path::PathBuf::new();
215 | output.push(name);
216 | output
217 | }
218 | }
219 | }
220 | None => {
221 | let mut output = std::path::PathBuf::new();
222 | output.push(output_file_name(
223 | &cli.dir_output,
224 | path,
225 | &cli.color_palette,
226 | &palettes,
227 | deltae::DEMethod::from(cli.method),
228 | ));
229 | output
230 | }
231 | };
232 |
233 | match image.save_with_format(&output_file_name, image::ImageFormat::Png) {
234 | Ok(_) => println!("Saved image: {:?}", output_file_name.display()),
235 | Err(err) => {
236 | eprintln!(
237 | "Encountered error while trying to save image \"{}\": {}",
238 | output_file_name.display(),
239 | err.if_supports_color(owo_colors::Stream::Stderr, |text| text.red())
240 | );
241 | std::process::exit(127)
242 | }
243 | };
244 |
245 | if cli.verbose >= 1 {
246 | let duration = start.elapsed().as_secs_f32();
247 | println!("Conversion took {} seconds.", duration);
248 | }
249 | }
250 |
251 | if cli.verbose >= 1 {
252 | let duration = total_start.elapsed().as_secs_f32();
253 | println!("Total duration: {} seconds.", duration);
254 | }
255 |
256 | Ok(())
257 | }
258 |
--------------------------------------------------------------------------------
/src/palettes.rs:
--------------------------------------------------------------------------------
1 | use serde_json::Value;
2 |
3 | use crate::cli::ColorPalette;
4 |
5 | impl ColorPalette {
6 | pub fn get_json(self) -> serde_json::Map {
7 | let colors = match self {
8 | ColorPalette::RawJSON { map } => return map,
9 | ColorPalette::Catppuccin => {
10 | serde_json::from_str(include_str!("./palettes/catppuccin.json")).unwrap()
11 | }
12 | ColorPalette::Dracula => {
13 | serde_json::from_str(include_str!("./palettes/dracula.json")).unwrap()
14 | }
15 | ColorPalette::Edge => {
16 | serde_json::from_str(include_str!("./palettes/edge.json")).unwrap()
17 | }
18 | ColorPalette::Everforest => {
19 | serde_json::from_str(include_str!("./palettes/everforest.json")).unwrap()
20 | }
21 | ColorPalette::Gruvbox => {
22 | serde_json::from_str(include_str!("./palettes/gruvbox.json")).unwrap()
23 | }
24 | ColorPalette::GruvboxMaterial => {
25 | serde_json::from_str(include_str!("./palettes/gruvbox-material.json")).unwrap()
26 | }
27 | ColorPalette::Nord => {
28 | serde_json::from_str(include_str!("./palettes/nord.json")).unwrap()
29 | }
30 | ColorPalette::OneDark => {
31 | serde_json::from_str(include_str!("./palettes/onedark.json")).unwrap()
32 | }
33 | ColorPalette::RosePine => {
34 | serde_json::from_str(include_str!("./palettes/rose-pine.json")).unwrap()
35 | }
36 | ColorPalette::Solarized => {
37 | serde_json::from_str(include_str!("./palettes/solarized.json")).unwrap()
38 | }
39 | ColorPalette::TokyoNight => {
40 | serde_json::from_str(include_str!("./palettes/tokyo-night.json")).unwrap()
41 | }
42 | };
43 | let Value::Object(obj) = colors else {
44 | panic!("An included theme appears to not be a JSON object?")
45 | };
46 | obj
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/palettes/catppuccin.json:
--------------------------------------------------------------------------------
1 | {
2 | "latte": {
3 | "rosewater": "#DC8A78",
4 | "flamingo": "#DD7878",
5 | "pink": "#EA76CB",
6 | "mauve": "#8839EF",
7 | "red": "#D20F39",
8 | "maroon": "#E64553",
9 | "peach": "#FE640B",
10 | "yellow": "#DF8E1D",
11 | "green": "#40A02B",
12 | "teal": "#179299",
13 | "sky": "#04A5E5",
14 | "sapphire": "#209FB5",
15 | "blue": "#1E66F5",
16 | "lavender": "#7287FD",
17 | "text": "#4C4F69",
18 | "subtext1": "#5C5F77",
19 | "subtext0": "#6C6F85",
20 | "overlay2": "#7C7F93",
21 | "overlay1": "#8C8FA1",
22 | "overlay0": "#9CA0B0",
23 | "surface2": "#ACB0BE",
24 | "surface1": "#BCC0CC",
25 | "surface0": "#CCD0DA",
26 | "crust": "#DCE0E8",
27 | "mantle": "#E6E9EF",
28 | "base": "#EFF1F5"
29 | },
30 | "frappe": {
31 | "rosewater": "#F2D5CF",
32 | "flamingo": "#EEBEBE",
33 | "pink": "#F4B8E4",
34 | "mauve": "#CA9EE6",
35 | "red": "#E78284",
36 | "maroon": "#EA999C",
37 | "peach": "#EF9F76",
38 | "yellow": "#E5C890",
39 | "green": "#A6D189",
40 | "teal": "#81C8BE",
41 | "sky": "#99D1DB",
42 | "sapphire": "#85C1DC",
43 | "blue": "#8CAAEE",
44 | "lavender": "#BABBF1",
45 | "text": "#C6D0F5",
46 | "subtext1": "#B5BFE2",
47 | "subtext0": "#A5ADCE",
48 | "overlay2": "#949CBB",
49 | "overlay1": "#838BA7",
50 | "overlay0": "#737994",
51 | "surface2": "#626880",
52 | "surface1": "#51576D",
53 | "surface0": "#414559",
54 | "base": "#303446",
55 | "mantle": "#292C3C",
56 | "crust": "#232634"
57 | },
58 | "macchiato": {
59 | "rosewater": "#F4DBD6",
60 | "flamingo": "#F0C6C6",
61 | "pink": "#F5BDE6",
62 | "mauve": "#C6A0F6",
63 | "red": "#ED8796",
64 | "maroon": "#EE99A0",
65 | "peach": "#F5A97F",
66 | "yellow": "#EED49F",
67 | "green": "#A6DA95",
68 | "teal": "#8BD5CA",
69 | "sky": "#91D7E3",
70 | "sapphire": "#7DC4E4",
71 | "blue": "#8AADF4",
72 | "lavender": "#B7BDF8",
73 | "text": "#CAD3F5",
74 | "subtext1": "#B8C0E0",
75 | "subtext0": "#A5ADCB",
76 | "overlay2": "#939AB7",
77 | "overlay1": "#8087A2",
78 | "overlay0": "#6E738D",
79 | "surface2": "#5B6078",
80 | "surface1": "#494D64",
81 | "surface0": "#363A4F",
82 | "base": "#24273A",
83 | "mantle": "#1E2030",
84 | "crust": "#181926"
85 | },
86 | "mocha": {
87 | "Rosewater": "#F5E0DC",
88 | "Flamingo": "#F2CDCD",
89 | "Pink": "#F5C2E7",
90 | "Mauve": "#CBA6F7",
91 | "Red": "#F38BA8",
92 | "Maroon": "#EBA0AC",
93 | "Peach": "#FAB387",
94 | "Yellow": "#F9E2AF",
95 | "Green": "#A6E3A1",
96 | "Teal": "#94E2D5",
97 | "Sky": "#89DCEB",
98 | "Sapphire": "#74C7EC",
99 | "Blue": "#89B4FA",
100 | "Lavender": "#B4BEFE",
101 | "Text": "#CDD6F4",
102 | "Subtext1": "#BAC2DE",
103 | "Subtext0": "#A6ADC8",
104 | "Overlay2": "#9399B2",
105 | "Overlay1": "#7F849C",
106 | "Overlay0": "#6C7086",
107 | "Surface2": "#585B70",
108 | "Surface1": "#45475A",
109 | "Surface0": "#313244",
110 | "Base": "#1E1E2E",
111 | "Mantle": "#181825",
112 | "Crust": "#11111B"
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/src/palettes/dracula.json:
--------------------------------------------------------------------------------
1 | {
2 | "Dracula": {
3 | "Background": "#282A36",
4 | "Selection": "#44475A",
5 | "Foreground": "#F8F8F2",
6 | "Comment": "#6272A4",
7 | "Cyan": "#8BE9FD",
8 | "Green": "#50FA7B",
9 | "Orange": "#FFB86C",
10 | "Pink": "#FF79C6",
11 | "Purple": "#BD93F9",
12 | "Red": "#FF5555",
13 | "Yellow": "#F1FA8C"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/palettes/edge.json:
--------------------------------------------------------------------------------
1 | {
2 | "Edge Dark": {
3 | "black": "#202023",
4 | "bg_dim": "#24262A",
5 | "bg0": "#2C2E34",
6 | "bg1": "#33353F",
7 | "bg2": "#363944",
8 | "bg3": "#3B3E48",
9 | "bg4": "#414550",
10 | "gray_dim": "#535C6A",
11 | "bg_red": "#EC7279",
12 | "diff_red": "#55393D",
13 | "bg_green": "#A0C980",
14 | "diff_green": "#394634",
15 | "bg_blue": "#6CB6EB",
16 | "diff_blue": "#354157",
17 | "bg_purple": "#D38AEA",
18 | "gray": "#758094",
19 | "red": "#EC7279",
20 | "yellow": "#DEB974",
21 | "green": "#A0C980",
22 | "cyan": "#5DBBC1",
23 | "blue": "#6CB6EB",
24 | "diff_yellow": "#4E432F",
25 | "purple": "#D38AEA",
26 | "fg": "#C5CDD9"
27 | },
28 | "Edge Dark (Aura)": {
29 | "black": "#202023",
30 | "bg_dim": "#24262D",
31 | "bg0": "#2B2D37",
32 | "bg1": "#333644",
33 | "bg2": "#363A49",
34 | "bg3": "#3A3E4E",
35 | "bg4": "#404455",
36 | "gray_dim": "#535C6A",
37 | "bg_red": "#EC7279",
38 | "diff_red": "#55393D",
39 | "bg_green": "#A0C980",
40 | "diff_green": "#394634",
41 | "bg_blue": "#6CB6EB",
42 | "diff_blue": "#354157",
43 | "bg_purple": "#D38AEA",
44 | "gray": "#758094",
45 | "red": "#EC7279",
46 | "yellow": "#DEB974",
47 | "green": "#A0C980",
48 | "cyan": "#5DBBC1",
49 | "blue": "#6CB6EB",
50 | "diff_yellow": "#4E432F",
51 | "purple": "#d38aea",
52 | "fg": "#C5CDD9"
53 | },
54 | "Edge Dark (Neon)": {
55 | "black": "#202023",
56 | "bg_dim": "#252630",
57 | "bg0": "#2B2D3A",
58 | "bg1": "#333648",
59 | "bg2": "#363A4E",
60 | "bg3": "#393E53",
61 | "bg4": "#3F445B",
62 | "gray_dim": "#535C6A",
63 | "bg_red": "#EC7279",
64 | "diff_red": "#55393D",
65 | "bg_green": "#A0C980",
66 | "diff_green": "#394634",
67 | "bg_blue": "#6CB6EB",
68 | "diff_blue": "#354157",
69 | "bg_purple": "#D38AEA",
70 | "gray": "#758094",
71 | "red": "#EC7279",
72 | "yellow": "#DEB974",
73 | "green": "#A0C980",
74 | "cyan": "#5DBBC1",
75 | "blue": "#6CB6EB",
76 | "diff_yellow": "#4E432F",
77 | "purple": "#D38AEA",
78 | "fg": "#C5CDD9"
79 | },
80 | "Edge Dark (Aura Dim)": {
81 | "black": "#202023",
82 | "bg_dim": "#24262D",
83 | "bg0": "#2B2D37",
84 | "bg1": "#333644",
85 | "bg2": "#363A49",
86 | "bg3": "#3A3E4E",
87 | "bg4": "#404455",
88 | "gray_dim": "#4F5866",
89 | "bg_red": "#EC7279",
90 | "diff_red": "#55393D",
91 | "bg_green": "#A0C980",
92 | "diff_green": "#394634",
93 | "bg_blue": "#6CB6EB",
94 | "diff_blue": "#354157",
95 | "bg_purple": "#D38AEA",
96 | "gray": "#677287",
97 | "red": "#EC7279",
98 | "yellow": "#DEB974",
99 | "green": "#A0C980",
100 | "cyan": "#5DBBC1",
101 | "blue": "#6CB6EB",
102 | "diff_yellow": "#4E432F",
103 | "purple": "#D38AEA",
104 | "fg": "#97A4B5"
105 | },
106 | "Edge Light": {
107 | "black": "#DDE2E7",
108 | "bg_dim": "#E8EBF0",
109 | "bg0": "#FAFAFA",
110 | "bg1": "#EEF1F4",
111 | "bg2": "#E8EBF0",
112 | "bg3": "#E8EBF0",
113 | "bg4": "#DDE2E7",
114 | "gray_dim": "#BAC3CB",
115 | "bg_red": "#E17373",
116 | "diff_red": "#F6E4E4",
117 | "bg_green": "#76AF6F",
118 | "diff_green": "#E5EEE4",
119 | "bg_blue": "#6996E0",
120 | "diff_blue": "#E3EAF6",
121 | "bg_purple": "#BF75D6",
122 | "gray": "#8790A0",
123 | "red": "#D05858",
124 | "yellow": "#BE7E05",
125 | "green": "#608E32",
126 | "cyan": "#3A8B84",
127 | "blue": "#5079BE",
128 | "diff_yellow": "#F0ECE2",
129 | "purple": "#B05CCC",
130 | "fg": "#4B505B"
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/src/palettes/everforest.json:
--------------------------------------------------------------------------------
1 | {
2 | "Dark": {
3 | "bg_dim": "#232A2E",
4 | "bg0": "#2D353B",
5 | "bg1": "#343F44",
6 | "bg2": "#3D484D",
7 | "bg3": "#475258",
8 | "bg4": "#4F585E",
9 | "bg5": "#56635F",
10 | "bg_red": "#543A48",
11 | "bg_visual": "#514045",
12 | "bg_yellow": "#4D4C43",
13 | "bg_green": "#425047",
14 | "bg_blue": "#3A515D",
15 | "red": "#E67E80",
16 | "orange": "#E69875",
17 | "yellow": "#DBBC7F",
18 | "green": "#A7C080",
19 | "blue": "#7FBBB3",
20 | "aqua": "#83C092",
21 | "purple": "#D699B6",
22 | "fg": "#D3C6AA",
23 | "statusline1": "#A7C080",
24 | "statusline2": "#D3C6AA",
25 | "statusline3": "#E67E80",
26 | "gray0": "#7A8478",
27 | "gray1": "#859289",
28 | "gray2": "#9DA9A0"
29 | },
30 | "Light": {
31 | "bg_dim": "#EFEBD4",
32 | "bg0": "#FDF6E3",
33 | "bg1": "#F4F0D9",
34 | "bg2": "#EFEBD4",
35 | "bg3": "#E6E2CC",
36 | "bg4": "#E0DCC7",
37 | "bg5": "#BDC3AF",
38 | "bg_red": "#FBE3DA",
39 | "bg_visual": "#EAEDC8",
40 | "bg_yellow": "#FAEDCD",
41 | "bg_green": "#F0F1D2",
42 | "bg_blue": "#E9F0E9",
43 | "red": "#F85552",
44 | "orange": "#F57D26",
45 | "yellow": "#DFA000",
46 | "green": "#8DA101",
47 | "blue": "#3A94C5",
48 | "aqua": "#35A77C",
49 | "purple": "#DF69BA",
50 | "fg": "#5C6A72",
51 | "statusline1": "#93B259",
52 | "statusline2": "#708089",
53 | "statusline3": "#E66868",
54 | "gray0": "#A6B0A0",
55 | "gray1": "#939F91",
56 | "gray2": "#829181"
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/palettes/gruvbox-material.json:
--------------------------------------------------------------------------------
1 | {
2 | "Dark": {
3 | "bg_dim": "#1B1B1B",
4 | "bg0": "#282828",
5 | "bg1": "#32302F",
6 | "bg2": "#32302F",
7 | "bg3": "#45403D",
8 | "bg4": "#45403D",
9 | "bg5": "#5A524C",
10 | "bg_statusline1": "#32302F",
11 | "bg_statusline2": "#3A3735",
12 | "bg_statusline3": "#504945",
13 | "bg_diff_green": "#34381B",
14 | "bg_visual_green": "#3B4439",
15 | "bg_diff_red": "#402120",
16 | "bg_visual_red": "#4C3432",
17 | "bg_diff_blue": "#0E363E",
18 | "bg_visual_blue": "#374141",
19 | "bg_visual_yellow": "#4F422E",
20 | "bg_current_word": "#3C3836",
21 | "fg0": "#D4BE98",
22 | "fg1": "#DDC7A1",
23 | "red": "#EA6962",
24 | "orange": "#E78A4E",
25 | "yellow": "#D8A657",
26 | "green": "#A9B665",
27 | "aqua": "#89B482",
28 | "blue": "#7DAEA3",
29 | "purple": "#D3869B",
30 | "bg_red": "#EA6962",
31 | "bg_green": "#A9B665",
32 | "bg_yellow": "#D8A657",
33 | "grey0": "#7C6F64",
34 | "grey1": "#928374",
35 | "grey2": "#A89984"
36 | },
37 | "Light": {
38 | "bg_dim": "#F2E5BC",
39 | "bg0": "#FBF1C7",
40 | "bg1": "#F4E8BE",
41 | "bg2": "#F2E5BC",
42 | "bg3": "#EEE0B7",
43 | "bg4": "#E5D5AD",
44 | "bg5": "#DDCCAB",
45 | "bg_statusline1": "#F2E5BC",
46 | "bg_statusline2": "#F2E5BC",
47 | "bg_statusline3": "#E5D5AD",
48 | "bg_diff_green": "#E6EABC",
49 | "bg_visual_green": "#DEE2B6",
50 | "bg_diff_red": "#F9E0BB",
51 | "bg_visual_red": "#F1D9B5",
52 | "bg_diff_blue": "#E2E6C7",
53 | "bg_visual_blue": "#DADEC0",
54 | "bg_visual_yellow": "#FAE7B3",
55 | "bg_current_word": "#F2E5BC",
56 | "fg0": "#654735",
57 | "fg1": "#4F3829",
58 | "red": "#C14A4A",
59 | "orange": "#C35E0A",
60 | "yellow": "#B47109",
61 | "green": "#6C782E",
62 | "aqua": "#4C7A5D",
63 | "blue": "#45707A",
64 | "purple": "#945E80",
65 | "bg_red": "#AE5858",
66 | "bg_green": "#6F8352",
67 | "bg_yellow": "#A96B2C",
68 | "grey0": "#A89984",
69 | "grey1": "#928374",
70 | "grey2": "#7C6F64"
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/palettes/gruvbox.json:
--------------------------------------------------------------------------------
1 | {
2 | "Dark mode": {
3 | "bg_0": "#282828",
4 | "red_0": "#CC241D",
5 | "green_0": "#98971A",
6 | "yellow_0": "#D79921",
7 | "blue_0": "#458588",
8 | "purple_0": "#B16286",
9 | "aqua_0": "#689D6A",
10 | "gray_0": "#A89984",
11 | "grey_1": "#928374",
12 | "red_1": "#FB4934",
13 | "green_1": "#B8BB26",
14 | "yellow_1": "#FABD2F",
15 | "blue_1": "#83A598",
16 | "purple_1": "#D3869B",
17 | "aqua_1": "#8EC07C",
18 | "fg_1": "#EBDBB2",
19 | "bg0_h_2": "#1D2021",
20 | "bg0_2": "#282828",
21 | "bg1_2": "#3C3836",
22 | "bg2_2": "#504945",
23 | "bg3_2": "#665C54",
24 | "bg4_2": "#7C6F64",
25 | "grey_2": "#928374",
26 | "orange_2": "#D65D0E",
27 | "bg0_s_3": "#32302F",
28 | "fg4_3": "#A89984",
29 | "fg3_3": "#BDAE93",
30 | "fg2_3": "#D5C4A1",
31 | "fg1_3": "#EBDBB2",
32 | "fg0_3": "#FBF1C7",
33 | "orange_3": "#FE8019"
34 | },
35 | "Light mode": {
36 | "bg_0": "#FBF1C7",
37 | "red_0": "#CC241D",
38 | "green_0": "#98971A",
39 | "yellow_0": "#D79921",
40 | "blue_0": "#458588",
41 | "purple_0": "#B16286",
42 | "aqua_0": "#689D6A",
43 | "gray_0": "#7C6F64",
44 | "grey_1": "#928374",
45 | "red_1": "#9D0006",
46 | "green_1": "#79740E",
47 | "yellow_1": "#B57614",
48 | "blue_1": "#076678",
49 | "purple_1": "#8F3F71",
50 | "aqua_1": "#427B58",
51 | "fg_1": "#3C3836",
52 | "bg0_h_2": "#F9F5D7",
53 | "bg0_2": "#FBF1C7",
54 | "bg1_2": "#EBDBB2",
55 | "bg2_2": "#D5C4A1",
56 | "bg3_2": "#BDAE93",
57 | "bg4_2": "#A89984",
58 | "grey_2": "#928374",
59 | "orange_2": "#D65D0E",
60 | "bg0_s_3": "#F2E5BC",
61 | "fg4_3": "#7C6F64",
62 | "fg3_3": "#665C54",
63 | "fg2_3": "#504945",
64 | "fg1_3": "#3C3836",
65 | "fg0_3": "#282828",
66 | "orange_3": "#AF3A03"
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/palettes/nord.json:
--------------------------------------------------------------------------------
1 | {
2 | "Polar Night": {
3 | "nord0": "#2E3440",
4 | "nord1": "#3B4252",
5 | "nord2": "#434C5E",
6 | "nord3": "#4C566A"
7 | },
8 | "Snow Storm": {
9 | "nord4": "#D8DEE9",
10 | "nord5": "#E5E9F0",
11 | "nord6": "#ECEFF4"
12 | },
13 | "Frost": {
14 | "nord7": "#8FBCBB",
15 | "nord8": "#88C0D0",
16 | "nord9": "#81A1C1",
17 | "nord10": "#5E81AC"
18 | },
19 | "Aurora": {
20 | "nord11": "#BF616A",
21 | "nord12": "#D08770",
22 | "nord13": "#EBCB8B",
23 | "nord14": "#A3BE8C",
24 | "nord15": "#B48EAD"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/palettes/onedark.json:
--------------------------------------------------------------------------------
1 | {
2 | "dark": {
3 | "black": "#181A1F",
4 | "bg0": "#282C34",
5 | "bg1": "#31353F",
6 | "bg2": "#393F4A",
7 | "bg3": "#3B3F4C",
8 | "bg_d": "#21252B",
9 | "bg_blue": "#73B8F1",
10 | "bg_yellow": "#EBD09C",
11 | "fg": "#ABB2BF",
12 | "purple": "#C678DD",
13 | "green": "#98C379",
14 | "orange": "#D19A66",
15 | "blue": "#61AFEF",
16 | "yellow": "#E5C07B",
17 | "cyan": "#56B6C2",
18 | "red": "#E86671",
19 | "grey": "#5C6370",
20 | "light_grey": "#848B98",
21 | "dark_cyan": "#2B6F77",
22 | "dark_red": "#993939",
23 | "dark_yellow": "#93691D",
24 | "dark_purple": "#8A3FA0",
25 | "diff_add": "#31392B",
26 | "diff_delete": "#382B2C",
27 | "diff_change": "#1C3448",
28 | "diff_text": "#2C5372"
29 | },
30 | "darker": {
31 | "black": "#0E1013",
32 | "bg0": "#1F2329",
33 | "bg1": "#282C34",
34 | "bg2": "#30363F",
35 | "bg3": "#323641",
36 | "bg_d": "#181B20",
37 | "bg_blue": "#61AFEF",
38 | "bg_yellow": "#E8C88C",
39 | "fg": "#A0A8B7",
40 | "purple": "#BF68D9",
41 | "green": "#8EBD6B",
42 | "orange": "#CC9057",
43 | "blue": "#4FA6ED",
44 | "yellow": "#E2B86B",
45 | "cyan": "#48B0BD",
46 | "red": "#E55561",
47 | "grey": "#535965",
48 | "light_grey": "#7A818E",
49 | "dark_cyan": "#266269",
50 | "dark_red": "#8B3434",
51 | "dark_yellow": "#835D1A",
52 | "dark_purple": "#7E3992",
53 | "diff_add": "#272E23",
54 | "diff_delete": "#2D2223",
55 | "diff_change": "#172A3A",
56 | "diff_text": "#274964"
57 | },
58 | "cool": {
59 | "black": "#151820",
60 | "bg0": "#242B38",
61 | "bg1": "#2D3343",
62 | "bg2": "#343E4F",
63 | "bg3": "#363C51",
64 | "bg_d": "#1E242E",
65 | "bg_blue": "#6DB9F7",
66 | "bg_yellow": "#F0D197",
67 | "fg": "#A5B0C5",
68 | "purple": "#CA72E4",
69 | "green": "#97CA72",
70 | "orange": "#D99A5E",
71 | "blue": "#5AB0F6",
72 | "yellow": "#EBC275",
73 | "cyan": "#4DBDCB",
74 | "red": "#EF5F6B",
75 | "grey": "#546178",
76 | "light_grey": "#7D899F",
77 | "dark_cyan": "#25747D",
78 | "dark_red": "#A13131",
79 | "dark_yellow": "#9A6B16",
80 | "dark_purple": "#8F36A9",
81 | "diff_add": "#303D27",
82 | "diff_delete": "#3C2729",
83 | "diff_change": "#18344C",
84 | "diff_text": "#265478"
85 | },
86 | "deep": {
87 | "black": "#0C0E15",
88 | "bg0": "#1A212E",
89 | "bg1": "#21283B",
90 | "bg2": "#283347",
91 | "bg3": "#2A324A",
92 | "bg_d": "#141B24",
93 | "bg_blue": "#54B0FD",
94 | "bg_yellow": "#F2CC81",
95 | "fg": "#93A4C3",
96 | "purple": "#C75AE8",
97 | "green": "#8BCD5B",
98 | "orange": "#DD9046",
99 | "blue": "#41A7FC",
100 | "yellow": "#EFBD5D",
101 | "cyan": "#34BFD0",
102 | "red": "#F65866",
103 | "grey": "#455574",
104 | "light_grey": "#6C7D9C",
105 | "dark_cyan": "#1B6A73",
106 | "dark_red": "#992525",
107 | "dark_yellow": "#8F610D",
108 | "dark_purple": "#862AA1",
109 | "diff_add": "#27341C",
110 | "diff_delete": "#331C1E",
111 | "diff_change": "#102B40",
112 | "diff_text": "#1C4A6E"
113 | },
114 | "warm": {
115 | "black": "#191A1C",
116 | "bg0": "#2C2D30",
117 | "bg1": "#35373B",
118 | "bg2": "#3E4045",
119 | "bg3": "#404247",
120 | "bg_d": "#242628",
121 | "bg_blue": "#79B7EB",
122 | "bg_yellow": "#E6CFA1",
123 | "fg": "#B1B4B9",
124 | "purple": "#C27FD7",
125 | "green": "#99BC80",
126 | "orange": "#C99A6E",
127 | "blue": "#68AEE8",
128 | "yellow": "#DFBE81",
129 | "cyan": "#5FAFB9",
130 | "red": "#E16D77",
131 | "grey": "#646568",
132 | "light_grey": "#8B8D91",
133 | "dark_cyan": "#316A71",
134 | "dark_red": "#914141",
135 | "dark_yellow": "#8C6724",
136 | "dark_purple": "#854897",
137 | "diff_add": "#32352F",
138 | "diff_delete": "#342F2F",
139 | "diff_change": "#203444",
140 | "diff_text": "#32526C"
141 | },
142 | "warmer": {
143 | "black": "#101012",
144 | "bg0": "#232326",
145 | "bg1": "#2C2D31",
146 | "bg2": "#35363B",
147 | "bg3": "#37383D",
148 | "bg_d": "#1B1C1E",
149 | "bg_blue": "#68AEE8",
150 | "bg_yellow": "#E2C792",
151 | "fg": "#A7AAB0",
152 | "purple": "#BB70D2",
153 | "green": "#8FB573",
154 | "orange": "#C49060",
155 | "blue": "#57A5E5",
156 | "yellow": "#DBB671",
157 | "cyan": "#51A8B3",
158 | "red": "#DE5D68",
159 | "grey": "#5A5B5E",
160 | "light_grey": "#818387",
161 | "dark_cyan": "#2B5D63",
162 | "dark_red": "#833B3B",
163 | "dark_yellow": "#7C5C20",
164 | "dark_purple": "#79428A",
165 | "diff_add": "#282B26",
166 | "diff_delete": "#2A2626",
167 | "diff_change": "#1A2A37",
168 | "diff_text": "#2C485F"
169 | },
170 | "light": {
171 | "black": "#101012",
172 | "bg0": "#FAFAFA",
173 | "bg1": "#F0F0F0",
174 | "bg2": "#E6E6E6",
175 | "bg3": "#DCDCDC",
176 | "bg_d": "#C9C9C9",
177 | "bg_blue": "#68AEE8",
178 | "bg_yellow": "#E2C792",
179 | "fg": "#383A42",
180 | "purple": "#A626A4",
181 | "green": "#50A14F",
182 | "orange": "#C18401",
183 | "blue": "#4078F2",
184 | "yellow": "#986801",
185 | "cyan": "#0184BC",
186 | "red": "#E45649",
187 | "grey": "#A0A1A7",
188 | "light_grey": "#818387",
189 | "dark_cyan": "#2B5D63",
190 | "dark_red": "#833B3B",
191 | "dark_yellow": "#7C5C20",
192 | "dark_purple": "#79428A",
193 | "diff_add": "#E2FBE4",
194 | "diff_delete": "#FCE2E5",
195 | "diff_change": "#E2ECFB",
196 | "diff_text": "#CAD3E0"
197 | }
198 | }
199 |
--------------------------------------------------------------------------------
/src/palettes/rose-pine.json:
--------------------------------------------------------------------------------
1 | {
2 | "Rose Pine": {
3 | "Base": "#191724",
4 | "Surface": "#1F1D2E",
5 | "Overlay": "#26233A",
6 | "Muted": "#6E6A86",
7 | "Subtle": "#908CAA",
8 | "Text": "#E0DEF4",
9 | "Love": "#EB6F92",
10 | "Gold": "#F6C177",
11 | "Rose": "#EBBCBA",
12 | "Pine": "#31748F",
13 | "Foam": "#9CCFD8",
14 | "Iris": "#C4A7E7",
15 | "Highlight Low": "#21202E",
16 | "Highlight Med": "#403D52",
17 | "Highlight High": "#524F67"
18 | },
19 | "Rose Pine Moon": {
20 | "Base": "#232136",
21 | "Surface": "#2A273F",
22 | "Overlay": "#393552",
23 | "Muted": "#6E6A86",
24 | "Subtle": "#908CAA",
25 | "Text": "#E0DEF4",
26 | "Love": "#EB6F92",
27 | "Gold": "#F6C177",
28 | "Rose": "#EA9A97",
29 | "Pine": "#3E8FB0",
30 | "Foam": "#9CCFD8",
31 | "Iris": "#C4A7E7",
32 | "Highlight Low": "#2A283E",
33 | "Highlight Med": "#44415A",
34 | "Highlight High": "#56526E"
35 | },
36 | "Rose Pine Dawn": {
37 | "Base": "#FAF4ED",
38 | "Surface": "#FFFAF3",
39 | "Overlay": "#F2E9E1",
40 | "Muted": "#9893A5",
41 | "Subtle": "#797593",
42 | "Text": "#575279",
43 | "Love": "#B4637A",
44 | "Gold": "#EA9D34",
45 | "Rose": "#D7827E",
46 | "Pine": "#286983",
47 | "Foam": "#56949F",
48 | "Iris": "#907AA9",
49 | "Highlight Low": "#F4EDE8",
50 | "Highlight Med": "#DFDAD9",
51 | "Highlight High": "#CECACD"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/palettes/solarized.json:
--------------------------------------------------------------------------------
1 | {
2 | "Solarized": {
3 | "base03": "#002B36",
4 | "base02": "#073642",
5 | "base01": "#586E75",
6 | "base00": "#657B83",
7 | "base0": "#839496",
8 | "base1": "#93A1A1",
9 | "base2": "#EEE8D5",
10 | "base3": "#FDF6E3",
11 | "yellow": "#B58900",
12 | "orange": "#CB4B16",
13 | "red": "#DC322F",
14 | "magenta": "#D33682",
15 | "violet": "#6C71C4",
16 | "blue": "#268BD2",
17 | "cyan": "#2AA198",
18 | "green": "#859900"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/palettes/tokyo-night.json:
--------------------------------------------------------------------------------
1 | {
2 | "Storm": {
3 | "background": "#24283B",
4 | "black": "#1D202F",
5 | "blue": "#7AA2F7",
6 | "brightBlack": "#414868",
7 | "brightBlue": "#7AA2F7",
8 | "brightCyan": "#7DCFFF",
9 | "brightGreen": "#9ECE6A",
10 | "brightPurple": "#9D7CD8",
11 | "brightRed": "#F7768E",
12 | "brightWhite": "#C0CAF5",
13 | "brightYellow": "#E0AF68",
14 | "cursorColor": "#C0CAF5",
15 | "cyan": "#7DCFFF",
16 | "foreground": "#C0CAF5",
17 | "green": "#9ECE6A",
18 | "purple": "#BB9AF7",
19 | "red": "#F7768E",
20 | "selectionBackground": "#2E3C64",
21 | "white": "#A9B1D6",
22 | "yellow": "#E0AF68"
23 | },
24 | "Night": {
25 | "background": "#1A1B26",
26 | "black": "#15161E",
27 | "blue": "#7AA2F7",
28 | "brightBlack": "#414868",
29 | "brightBlue": "#7AA2F7",
30 | "brightCyan": "#7DCFFF",
31 | "brightGreen": "#9ECE6A",
32 | "brightPurple": "#9D7CD8",
33 | "brightRed": "#F7768E",
34 | "brightWhite": "#C0CAF5",
35 | "brightYellow": "#E0AF68",
36 | "cursorColor": "#C0CAF5",
37 | "cyan": "#7DCFFF",
38 | "foreground": "#C0CAF5",
39 | "green": "#9ECE6A",
40 | "purple": "#BB9AF7",
41 | "red": "#F7768E",
42 | "selectionBackground": "#283457",
43 | "white": "#A9B1D6",
44 | "yellow": "#E0AF68"
45 | },
46 | "Moon": {
47 | "background": "#222436",
48 | "black": "#1B1D2B",
49 | "blue": "#82AAFF",
50 | "brightBlack": "#444A73",
51 | "brightBlue": "#82AAFF",
52 | "brightCyan": "#86E1FC",
53 | "brightGreen": "#C3E88D",
54 | "brightPurple": "#FCA7EA",
55 | "brightRed": "#FF757F",
56 | "brightWhite": "#C8D3F5",
57 | "brightYellow": "#FFC777",
58 | "cursorColor": "#C8D3F5",
59 | "cyan": "#86E1FC",
60 | "foreground": "#C8D3F5",
61 | "green": "#C3E88D",
62 | "purple": "#C099FF",
63 | "red": "#FF757F",
64 | "selectionBackground": "#2D3F76",
65 | "white": "#828BB8",
66 | "yellow": "#FFC777"
67 | },
68 | "Day": {
69 | "background": "#E1E2E7",
70 | "black": "#E9E9ED",
71 | "blue": "#2E7DE9",
72 | "brightBlack": "#A1A6C5",
73 | "brightBlue": "#2E7DE9",
74 | "brightCyan": "#007197",
75 | "brightGreen": "#587539",
76 | "brightPurple": "#7847BD",
77 | "brightRed": "#F52A65",
78 | "brightWhite": "#3760BF",
79 | "brightYellow": "#8C6C3E",
80 | "cursorColor": "#3760BF",
81 | "cyan": "#007197",
82 | "foreground": "#3760BF",
83 | "green": "#587539",
84 | "purple": "#9854F1",
85 | "red": "#F52A65",
86 | "selectionBackground": "#B6BFE2",
87 | "white": "#6172B0",
88 | "yellow": "#8C6C3E"
89 | }
90 | }
91 |
--------------------------------------------------------------------------------