#[allow(unused)]
use crate::{buffer, Document, Error, Result};
#[cfg(feature = "import")]
#[cfg_attr(docsrs, doc(cfg(feature = "import")))]
use image_crate::DynamicImage;
#[cfg(feature = "extensions")]
use serde_json::{Map, Value};
#[cfg(feature = "import")]
#[cfg_attr(docsrs, doc(cfg(feature = "import")))]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum Format {
R8,
R8G8,
R8G8B8,
R8G8B8A8,
R16,
R16G16,
R16G16B16,
R16G16B16A16,
R32G32B32FLOAT,
R32G32B32A32FLOAT,
}
#[derive(Clone, Debug)]
pub enum Source<'a> {
View {
view: buffer::View<'a>,
mime_type: &'a str,
},
Uri {
uri: &'a str,
mime_type: Option<&'a str>,
},
}
#[derive(Clone, Debug)]
pub struct Image<'a> {
document: &'a Document,
index: usize,
json: &'a json::image::Image,
}
#[cfg(feature = "import")]
#[cfg_attr(docsrs, doc(cfg(feature = "import")))]
#[derive(Clone, Debug)]
pub struct Data {
pub pixels: Vec<u8>,
pub format: Format,
pub width: u32,
pub height: u32,
}
impl<'a> Image<'a> {
pub(crate) fn new(document: &'a Document, index: usize, json: &'a json::image::Image) -> Self {
Self {
document,
index,
json,
}
}
pub fn index(&self) -> usize {
self.index
}
#[cfg(feature = "names")]
#[cfg_attr(docsrs, doc(cfg(feature = "names")))]
pub fn name(&self) -> Option<&'a str> {
self.json.name.as_deref()
}
pub fn source(&self) -> Source<'a> {
if let Some(index) = self.json.buffer_view.as_ref() {
let view = self.document.views().nth(index.value()).unwrap();
let mime_type = self.json.mime_type.as_ref().map(|x| x.0.as_str()).unwrap();
Source::View { view, mime_type }
} else {
let uri = self.json.uri.as_ref().unwrap();
let mime_type = self.json.mime_type.as_ref().map(|x| x.0.as_str());
Source::Uri { uri, mime_type }
}
}
#[cfg(feature = "extensions")]
#[cfg_attr(docsrs, doc(cfg(feature = "extensions")))]
pub fn extensions(&self) -> Option<&Map<String, Value>> {
let ext = self.json.extensions.as_ref()?;
Some(&ext.others)
}
#[cfg(feature = "extensions")]
#[cfg_attr(docsrs, doc(cfg(feature = "extensions")))]
pub fn extension_value(&self, ext_name: &str) -> Option<&Value> {
let ext = self.json.extensions.as_ref()?;
ext.others.get(ext_name)
}
pub fn extras(&self) -> &'a json::Extras {
&self.json.extras
}
}
#[cfg(feature = "import")]
impl Data {
pub(crate) fn new(image: DynamicImage) -> Result<Self> {
use image_crate::GenericImageView;
let format = match image {
DynamicImage::ImageLuma8(_) => Format::R8,
DynamicImage::ImageLumaA8(_) => Format::R8G8,
DynamicImage::ImageRgb8(_) => Format::R8G8B8,
DynamicImage::ImageRgba8(_) => Format::R8G8B8A8,
DynamicImage::ImageLuma16(_) => Format::R16,
DynamicImage::ImageLumaA16(_) => Format::R16G16,
DynamicImage::ImageRgb16(_) => Format::R16G16B16,
DynamicImage::ImageRgba16(_) => Format::R16G16B16A16,
DynamicImage::ImageRgb32F(_) => Format::R32G32B32FLOAT,
DynamicImage::ImageRgba32F(_) => Format::R32G32B32A32FLOAT,
image => return Err(Error::UnsupportedImageFormat(image)),
};
let (width, height) = image.dimensions();
let pixels = image.into_bytes();
Ok(Data {
format,
width,
height,
pixels,
})
}
}