Skip to main content

imagesize/formats/
mod.rs

1#[cfg(feature = "aesprite")]
2pub mod aesprite;
3#[cfg(feature = "bmp")]
4pub mod bmp;
5#[cfg(feature = "dds")]
6pub mod dds;
7#[cfg(feature = "exr")]
8pub mod exr;
9#[cfg(feature = "farbfeld")]
10pub mod farbfeld;
11#[cfg(feature = "gif")]
12pub mod gif;
13#[cfg(feature = "hdr")]
14pub mod hdr;
15#[cfg(feature = "ico")]
16pub mod ico;
17#[cfg(feature = "ilbm")]
18pub mod ilbm;
19#[cfg(feature = "jpeg")]
20pub mod jpeg;
21#[cfg(feature = "jxl")]
22pub mod jxl;
23#[cfg(feature = "ktx2")]
24pub mod ktx2;
25#[cfg(feature = "png")]
26pub mod png;
27#[cfg(feature = "pnm")]
28pub mod pnm;
29#[cfg(feature = "psd")]
30pub mod psd;
31#[cfg(feature = "qoi")]
32pub mod qoi;
33#[cfg(feature = "tga")]
34pub mod tga;
35#[cfg(feature = "tiff")]
36pub mod tiff;
37#[cfg(feature = "vtf")]
38pub mod vtf;
39#[cfg(feature = "webp")]
40pub mod webp;
41
42use crate::{container, ImageError, ImageResult, ImageType};
43use std::io::{BufRead, Seek};
44
45pub fn image_type<R: BufRead + Seek>(reader: &mut R) -> ImageResult<ImageType> {
46    let mut header = [0; 12];
47    reader.read_exact(&mut header)?;
48
49    // Currently there are no formats where 1 byte is enough to determine format
50    if header.len() < 2 {
51        return Err(
52            std::io::Error::new(std::io::ErrorKind::UnexpectedEof, "Not enough data").into(),
53        );
54    }
55
56    // This is vaguely organized in what I assume are the most commonly used formats.
57    // I don't know how much this matters for actual execution time.
58    #[cfg(feature = "jpeg")]
59    if jpeg::matches(&header) {
60        return Ok(ImageType::Jpeg);
61    }
62
63    #[cfg(feature = "png")]
64    if png::matches(&header) {
65        return Ok(ImageType::Png);
66    }
67
68    #[cfg(feature = "gif")]
69    if gif::matches(&header) {
70        return Ok(ImageType::Gif);
71    }
72
73    #[cfg(feature = "tiff")]
74    if tiff::matches(&header) {
75        return Ok(ImageType::Tiff);
76    }
77
78    #[cfg(feature = "webp")]
79    if webp::matches(&header) {
80        return Ok(ImageType::Webp);
81    }
82
83    #[cfg(feature = "heif")]
84    if let Some(c) = container::heif::matches(&header, reader) {
85        return Ok(ImageType::Heif(c));
86    }
87
88    #[cfg(feature = "jxl")]
89    if jxl::matches(&header) {
90        return Ok(ImageType::Jxl);
91    }
92
93    #[cfg(feature = "bmp")]
94    if bmp::matches(&header) {
95        return Ok(ImageType::Bmp);
96    }
97
98    #[cfg(feature = "psd")]
99    if psd::matches(&header) {
100        return Ok(ImageType::Psd);
101    }
102
103    #[cfg(feature = "ico")]
104    if ico::matches(&header) {
105        return Ok(ImageType::Ico);
106    }
107
108    #[cfg(feature = "aesprite")]
109    if aesprite::matches(&header) {
110        return Ok(ImageType::Aseprite);
111    }
112
113    #[cfg(feature = "exr")]
114    if exr::matches(&header) {
115        return Ok(ImageType::Exr);
116    }
117
118    #[cfg(feature = "hdr")]
119    if hdr::matches(&header) {
120        return Ok(ImageType::Hdr);
121    }
122
123    #[cfg(feature = "dds")]
124    if dds::matches(&header) {
125        return Ok(ImageType::Dds);
126    }
127
128    #[cfg(feature = "ktx2")]
129    if ktx2::matches(&header) {
130        return Ok(ImageType::Ktx2);
131    }
132
133    #[cfg(feature = "qoi")]
134    if qoi::matches(&header) {
135        return Ok(ImageType::Qoi);
136    }
137
138    #[cfg(feature = "farbfeld")]
139    if farbfeld::matches(&header) {
140        return Ok(ImageType::Farbfeld);
141    }
142
143    #[cfg(feature = "pnm")]
144    if pnm::matches(&header) {
145        return Ok(ImageType::Pnm);
146    }
147
148    #[cfg(feature = "vtf")]
149    if vtf::matches(&header) {
150        return Ok(ImageType::Vtf);
151    }
152
153    #[cfg(feature = "ilbm")]
154    if ilbm::matches(&header) {
155        return Ok(ImageType::Ilbm);
156    }
157
158    // Keep TGA last because it has the highest probability of false positives
159    #[cfg(feature = "tga")]
160    if tga::matches(&header, reader) {
161        return Ok(ImageType::Tga);
162    }
163
164    Err(ImageError::NotSupported)
165}