1#[cfg(feature = "aesprite")]
2pub mod aesprite;
3#[cfg(feature = "astc")]
4pub mod astc;
5#[cfg(feature = "bmp")]
6pub mod bmp;
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 if header.len() < 2 {
51 return Err(
52 std::io::Error::new(std::io::ErrorKind::UnexpectedEof, "Not enough data").into(),
53 );
54 }
55
56 #[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 = "astc")]
114 if astc::matches(&header) {
115 return Ok(ImageType::Astc);
116 }
117
118 #[cfg(feature = "atc")]
119 if container::atc::matches(&header) {
120 use crate::container::atc::AtcCompression;
121
122 let compression =
123 container::atc::detect_compression(reader).unwrap_or(AtcCompression::Unknown);
124 return Ok(ImageType::Atc(compression));
125 }
126
127 #[cfg(feature = "pvrtc")]
128 if container::pvrtc::matches(&header) {
129 use crate::container::pvrtc::PvrtcCompression;
130
131 let compression =
132 container::pvrtc::detect_compression(reader).unwrap_or(PvrtcCompression::Unknown);
133 return Ok(ImageType::Pvrtc(compression));
134 }
135
136 #[cfg(feature = "eac")]
138 if container::pkm::matches_eac(&header) {
139 use crate::container::pkm::PkmCompression;
140
141 let compression =
142 container::pkm::detect_compression(reader).unwrap_or(PkmCompression::Unknown);
143 return Ok(ImageType::Eac(compression));
144 }
145
146 #[cfg(feature = "etc2")]
147 if container::pkm::matches(&header) {
148 use crate::container::pkm::PkmCompression;
149
150 let compression =
151 container::pkm::detect_compression(reader).unwrap_or(PkmCompression::Unknown);
152 return Ok(ImageType::Etc2(compression));
153 }
154
155 #[cfg(feature = "exr")]
156 if exr::matches(&header) {
157 return Ok(ImageType::Exr);
158 }
159
160 #[cfg(feature = "hdr")]
161 if hdr::matches(&header) {
162 return Ok(ImageType::Hdr);
163 }
164
165 #[cfg(feature = "dds")]
166 if container::dds::matches(&header) {
167 use crate::container::dds::DdsCompression;
168
169 let compression =
170 container::dds::detect_compression(reader).unwrap_or(DdsCompression::Unknown);
171 return Ok(ImageType::Dds(compression));
172 }
173
174 #[cfg(feature = "ktx2")]
175 if ktx2::matches(&header) {
176 return Ok(ImageType::Ktx2);
177 }
178
179 #[cfg(feature = "qoi")]
180 if qoi::matches(&header) {
181 return Ok(ImageType::Qoi);
182 }
183
184 #[cfg(feature = "farbfeld")]
185 if farbfeld::matches(&header) {
186 return Ok(ImageType::Farbfeld);
187 }
188
189 #[cfg(feature = "pnm")]
190 if pnm::matches(&header) {
191 return Ok(ImageType::Pnm);
192 }
193
194 #[cfg(feature = "vtf")]
195 if vtf::matches(&header) {
196 return Ok(ImageType::Vtf);
197 }
198
199 #[cfg(feature = "ilbm")]
200 if ilbm::matches(&header) {
201 return Ok(ImageType::Ilbm);
202 }
203
204 #[cfg(feature = "tga")]
206 if tga::matches(&header, reader) {
207 return Ok(ImageType::Tga);
208 }
209
210 Err(ImageError::NotSupported)
211}