Skip to content

Commit

Permalink
Merge pull request #425 from marstaik/ms-webp
Browse files Browse the repository at this point in the history
Add support for `EXT_texture_webp` v2
  • Loading branch information
alteous authored Jul 3, 2024
2 parents 0f1e94f + 8baf835 commit a29fb75
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 7 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ KHR_materials_variants = ["gltf-json/KHR_materials_variants"]
KHR_materials_volume = ["gltf-json/KHR_materials_volume"]
KHR_materials_specular = ["gltf-json/KHR_materials_specular"]
KHR_materials_emissive_strength = ["gltf-json/KHR_materials_emissive_strength"]
EXT_texture_webp = ["gltf-json/EXT_texture_webp", "image/webp"]
guess_mime_type = []

[[example]]
Expand Down
1 change: 1 addition & 0 deletions gltf-json/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ KHR_materials_variants = []
KHR_materials_volume = []
KHR_texture_transform = []
KHR_materials_emissive_strength = []
EXT_texture_webp = []
3 changes: 2 additions & 1 deletion gltf-json/src/extensions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub const ENABLED_EXTENSIONS: &[&str] = &[
// Allowlisted texture extensions. Processing is delegated to the user.
#[cfg(feature = "allow_empty_texture")]
"KHR_texture_basisu",
#[cfg(feature = "allow_empty_texture")]
#[cfg(feature = "EXT_texture_webp")]
"EXT_texture_webp",
#[cfg(feature = "allow_empty_texture")]
"MSFT_texture_dds",
Expand All @@ -70,4 +70,5 @@ pub const SUPPORTED_EXTENSIONS: &[&str] = &[
"KHR_materials_transmission",
"KHR_materials_ior",
"KHR_materials_emissive_strength",
"EXT_texture_webp",
];
20 changes: 19 additions & 1 deletion gltf-json/src/extensions/texture.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#[cfg(feature = "KHR_texture_transform")]
#[cfg(any(feature = "KHR_texture_transform", feature = "EXT_texture_webp"))]
use crate::{extras::Extras, validation::Validate};
#[cfg(feature = "EXT_texture_webp")]
use crate::{image, Index};

use gltf_derive::Validate;
use serde_derive::{Deserialize, Serialize};
#[cfg(feature = "extensions")]
Expand All @@ -19,6 +22,21 @@ pub struct Texture {
#[cfg(feature = "extensions")]
#[serde(default, flatten)]
pub others: Map<String, Value>,

#[cfg(feature = "EXT_texture_webp")]
#[serde(
default,
rename = "EXT_texture_webp",
skip_serializing_if = "Option::is_none"
)]
pub texture_webp: Option<TextureWebp>,
}

#[cfg(feature = "EXT_texture_webp")]
#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
pub struct TextureWebp {
/// The index of the webp image used by the texture.
pub source: Index<image::Image>,
}

#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
Expand Down
7 changes: 6 additions & 1 deletion gltf-json/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ use gltf_derive::Validate;
use serde_derive::{Deserialize, Serialize};

/// All valid MIME types.
pub const VALID_MIME_TYPES: &[&str] = &["image/jpeg", "image/png"];
pub const VALID_MIME_TYPES: &[&str] = &[
"image/jpeg",
"image/png",
#[cfg(feature = "EXT_texture_webp")]
"image/webp",
];

/// Image data used to create a texture.
#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
Expand Down
32 changes: 30 additions & 2 deletions gltf-json/src/texture.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::extensions::texture;
use crate::validation::{Checked, Validate};
use crate::{extensions, image, Extras, Index};
use gltf_derive::Validate;
Expand Down Expand Up @@ -179,7 +180,7 @@ where
P: Fn() -> crate::Path,
R: FnMut(&dyn Fn() -> crate::Path, crate::validation::Error),
{
if cfg!(feature = "allow_empty_texture") {
if cfg!(any(feature = "allow_empty_texture",)) {
if !source_is_empty(source) {
source.validate(root, path, report);
}
Expand Down Expand Up @@ -217,6 +218,27 @@ pub struct Texture {
pub extras: Extras,
}

impl Texture {
/// The index of the image used by this texture.
pub fn primary_source(&self) -> Index<image::Image> {
#[allow(unused_mut)]
let mut source = self.source;
#[cfg(feature = "EXT_texture_webp")]
{
if let Some(texture_webp) = &self.extensions {
if let Some(texture_webp) = &texture_webp.texture_webp {
// Only use the webp source if the source is not empty
// Otherwise, fallback to whatever was there originally
if !source_is_empty(&texture_webp.source) {
source = texture_webp.source;
}
}
}
}
source
}
}

impl Validate for Texture {
fn validate<P, R>(&self, root: &crate::Root, path: P, report: &mut R)
where
Expand All @@ -227,7 +249,13 @@ impl Validate for Texture {
.validate(root, || path().field("sampler"), report);
self.extensions
.validate(root, || path().field("extensions"), report);
source_validate(&self.source, root, || path().field("source"), report);

source_validate(
&self.primary_source(),
root,
|| path().field("source"),
report,
);
}
}

Expand Down
12 changes: 12 additions & 0 deletions src/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use std::borrow::Cow;
use std::{fs, io};

use crate::{Document, Error, Gltf, Result};
#[cfg(feature = "EXT_texture_webp")]
use image_crate::ImageFormat::WebP;
use image_crate::ImageFormat::{Jpeg, Png};
use std::path::Path;

Expand Down Expand Up @@ -148,6 +150,8 @@ impl image::Data {
let guess_format = |encoded_image: &[u8]| match image_crate::guess_format(encoded_image) {
Ok(image_crate::ImageFormat::Png) => Some(Png),
Ok(image_crate::ImageFormat::Jpeg) => Some(Jpeg),
#[cfg(feature = "EXT_texture_webp")]
Ok(image_crate::ImageFormat::WebP) => Some(WebP),
_ => None,
};
#[cfg(not(feature = "guess_mime_type"))]
Expand All @@ -159,6 +163,8 @@ impl image::Data {
let encoded_format = match annoying_case {
"image/png" => Png,
"image/jpeg" => Jpeg,
#[cfg(feature = "EXT_texture_webp")]
"image/webp" => WebP,
_ => match guess_format(&encoded_image) {
Some(format) => format,
None => return Err(Error::UnsupportedImageEncoding),
Expand All @@ -173,13 +179,17 @@ impl image::Data {
let encoded_format = match mime_type {
Some("image/png") => Png,
Some("image/jpeg") => Jpeg,
#[cfg(feature = "EXT_texture_webp")]
Some("image/webp") => WebP,
Some(_) => match guess_format(&encoded_image) {
Some(format) => format,
None => return Err(Error::UnsupportedImageEncoding),
},
None => match uri.rsplit('.').next() {
Some("png") => Png,
Some("jpg") | Some("jpeg") => Jpeg,
#[cfg(feature = "EXT_texture_webp")]
Some("webp") => WebP,
_ => match guess_format(&encoded_image) {
Some(format) => format,
None => return Err(Error::UnsupportedImageEncoding),
Expand All @@ -197,6 +207,8 @@ impl image::Data {
let encoded_format = match mime_type {
"image/png" => Png,
"image/jpeg" => Jpeg,
#[cfg(feature = "EXT_texture_webp")]
"image/webp" => WebP,
_ => match guess_format(encoded_image) {
Some(format) => format,
None => return Err(Error::UnsupportedImageEncoding),
Expand Down
4 changes: 2 additions & 2 deletions src/texture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ impl<'a> Texture<'a> {
/// Returns the image used by this texture.
#[cfg(feature = "allow_empty_texture")]
pub fn source(&self) -> Option<image::Image<'a>> {
let index = self.json.source.value();
let index = self.json.primary_source().value();
if index == u32::MAX as usize {
None
} else {
Expand All @@ -173,7 +173,7 @@ impl<'a> Texture<'a> {
pub fn source(&self) -> image::Image<'a> {
self.document
.images()
.nth(self.json.source.value())
.nth(self.json.primary_source().value())
.unwrap()
}

Expand Down

0 comments on commit a29fb75

Please sign in to comment.