1#[allow(unused)]
2use crate::{buffer, Document, Error, Result};
3
4#[cfg(feature = "import")]
5#[cfg_attr(docsrs, doc(cfg(feature = "import")))]
6use image_crate::DynamicImage;
7#[cfg(feature = "extensions")]
8use serde_json::{Map, Value};
9
10#[cfg(feature = "import")]
12#[cfg_attr(docsrs, doc(cfg(feature = "import")))]
13#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
14pub enum Format {
15 R8,
17
18 R8G8,
20
21 R8G8B8,
23
24 R8G8B8A8,
26
27 R16,
29
30 R16G16,
32
33 R16G16B16,
35
36 R16G16B16A16,
38
39 R32G32B32FLOAT,
41
42 R32G32B32A32FLOAT,
44}
45
46#[derive(Clone, Debug)]
48pub enum Source<'a> {
49 View {
51 view: buffer::View<'a>,
53
54 mime_type: &'a str,
56 },
57
58 Uri {
60 uri: &'a str,
62
63 mime_type: Option<&'a str>,
65 },
66}
67
68#[derive(Clone, Debug)]
70pub struct Image<'a> {
71 document: &'a Document,
73
74 index: usize,
76
77 json: &'a json::image::Image,
79}
80
81#[cfg(feature = "import")]
83#[cfg_attr(docsrs, doc(cfg(feature = "import")))]
84#[derive(Clone, Debug)]
85pub struct Data {
86 pub pixels: Vec<u8>,
88
89 pub format: Format,
91
92 pub width: u32,
94
95 pub height: u32,
97}
98
99impl<'a> Image<'a> {
100 pub(crate) fn new(document: &'a Document, index: usize, json: &'a json::image::Image) -> Self {
102 Self {
103 document,
104 index,
105 json,
106 }
107 }
108
109 pub fn index(&self) -> usize {
111 self.index
112 }
113
114 #[cfg(feature = "names")]
116 #[cfg_attr(docsrs, doc(cfg(feature = "names")))]
117 pub fn name(&self) -> Option<&'a str> {
118 self.json.name.as_deref()
119 }
120
121 pub fn source(&self) -> Source<'a> {
123 if let Some(index) = self.json.buffer_view.as_ref() {
124 let view = self.document.views().nth(index.value()).unwrap();
125 let mime_type = self.json.mime_type.as_ref().map(|x| x.0.as_str()).unwrap();
126 Source::View { view, mime_type }
127 } else {
128 let uri = self.json.uri.as_ref().unwrap();
129 let mime_type = self.json.mime_type.as_ref().map(|x| x.0.as_str());
130 Source::Uri { uri, mime_type }
131 }
132 }
133
134 #[cfg(feature = "extensions")]
136 #[cfg_attr(docsrs, doc(cfg(feature = "extensions")))]
137 pub fn extensions(&self) -> Option<&Map<String, Value>> {
138 let ext = self.json.extensions.as_ref()?;
139 Some(&ext.others)
140 }
141
142 #[cfg(feature = "extensions")]
144 #[cfg_attr(docsrs, doc(cfg(feature = "extensions")))]
145 pub fn extension_value(&self, ext_name: &str) -> Option<&Value> {
146 let ext = self.json.extensions.as_ref()?;
147 ext.others.get(ext_name)
148 }
149
150 pub fn extras(&self) -> &'a json::Extras {
152 &self.json.extras
153 }
154}
155
156#[cfg(feature = "import")]
157impl Data {
158 pub(crate) fn new(image: DynamicImage) -> Result<Self> {
161 use image_crate::GenericImageView;
162 let format = match image {
163 DynamicImage::ImageLuma8(_) => Format::R8,
164 DynamicImage::ImageLumaA8(_) => Format::R8G8,
165 DynamicImage::ImageRgb8(_) => Format::R8G8B8,
166 DynamicImage::ImageRgba8(_) => Format::R8G8B8A8,
167 DynamicImage::ImageLuma16(_) => Format::R16,
168 DynamicImage::ImageLumaA16(_) => Format::R16G16,
169 DynamicImage::ImageRgb16(_) => Format::R16G16B16,
170 DynamicImage::ImageRgba16(_) => Format::R16G16B16A16,
171 DynamicImage::ImageRgb32F(_) => Format::R32G32B32FLOAT,
172 DynamicImage::ImageRgba32F(_) => Format::R32G32B32A32FLOAT,
173 image => return Err(Error::UnsupportedImageFormat(image)),
174 };
175 let (width, height) = image.dimensions();
176 let pixels = image.into_bytes();
177 Ok(Data {
178 format,
179 width,
180 height,
181 pixels,
182 })
183 }
184}