1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//! [`feim`](https://sr.ht/~sugo/feim) is a crate designed with some clues from
//! [libgoimg](https://github.com/sug0/libgoimg), which in turn was heavily influeced
//! by the API of [Go's image package](https://pkg.go.dev/image). One of the goals
//! of `feim` was to increase the flexibility users had to work with images, namely
//! rolling their own custom serialization routines, color formats and image formats.
//!
//! ## Encoding
//!
//! Here is a simple white background being saved to a file `out.png`:
//!
//! ```rust,no_run
//! use std::fs::File;
//! use std::io::{self, BufWriter};
//!
//! use feim::buffer::RawPixBuf;
//! use feim::image::png::Png;
//! use feim::color::Rgb;
//! use feim::image::ImageMut;
//! use feim::serialize::EncodeSpecialized;
//!
//! const DIM: usize = 250;
//!
//! fn main() -> io::Result<()> {
//! let output = File::create("out.png")?;
//! let output = BufWriter::new(output);
//!
//! let mut image = RawPixBuf::new(DIM, DIM);
//! draw_image(&mut image);
//!
//! let opts = Default::default();
//! Png::encode_specialized(output, opts, &image)
//! }
//!
//! fn draw_image(buf: &mut RawPixBuf<Rgb>) {
//! const WHITE: Rgb = Rgb { r: 255, g: 255, b: 255 };
//!
//! for y in 0..DIM {
//! for x in 0..DIM {
//! buf.pixel_set(x, y, WHITE);
//! }
//! }
//! }
//! ```
//!
//! ## Decoding
//!
//! Decoding images with `feim` is as simples as:
//!
//! ```rust,no_run
//! use std::io::{self, BufReader, BufWriter, Write};
//!
//! use feim::buffer::RawPixBuf;
//! use feim::image::jpeg::Jpeg;
//! use feim::color::Nrgba64Be;
//! use feim::image::Format;
//! use feim::image::farbfeld::{Farbfeld, FarbfeldDecodeOptions};
//! use feim::serialize::{try_format, EncodeSpecialized, Decode};
//!
//! fn main() -> io::Result<()> {
//! let stdin = io::stdin();
//! let stdin_lock = stdin.lock();
//! let mut stdin_reader = BufReader::new(stdin_lock);
//!
//! let stdout = io::stdout();
//! let stdout_lock = stdout.lock();
//! let mut stdout_writer = BufWriter::new(stdout_lock);
//!
//! let formats: [(usize, &dyn Format); 2] = [
//! (0, &Farbfeld),
//! (1, &Jpeg),
//! ];
//!
//! match try_format(&mut stdin_reader, formats) {
//! Ok(Some(0)) => {
//! let opts = FarbfeldDecodeOptions {
//! check_header: false,
//! };
//! let image: RawPixBuf<Nrgba64Be> = Farbfeld::decode(stdin_reader, opts)?;
//! let _ = write!(&mut stdout_writer, "{:#?}", image);
//! Ok(())
//! },
//! Ok(Some(1)) => {
//! let image = Jpeg::decode(stdin_reader, ())?;
//! let _ = write!(&mut stdout_writer, "{:#?}", image);
//! Ok(())
//! },
//! Ok(Some(_)) => unreachable!(),
//! Ok(None) => panic!("Image format not supported"),
//! Err(e) => Err(e),
//! }
//! }
//! ```
//!
//! Note that you should be using [`BuiltInFormat`](crate::image::BuiltInFormat) as the
//! tag type passed to [`try_format`](crate::serialize::try_format) instead of integers.
//! A readily available iterator with all built-in formats is available under
//! [`built_in_formats_iter`](crate::image::built_in_formats_iter).