Feature-gate all image formats (#15586)

# Objective

Bevy supports feature gates for each format it supports, but several
formats that it loads via the `image` crate do not have feature gates.
Additionally, the QOI format is supported by the `image` crate and
wasn't available at all. This fixes that.

## Solution

The following feature gates are added:

* `avif`
* `ff` (Farbfeld)
* `gif`
* `ico`
* `qoi`
* `tiff`

None of these formats are enabled by default, despite the fact that all
these formats appeared to be enabled by default before. Since
`default-features` was disabled for the `image` crate, it's likely that
using any of these formats would have errored by default before this
change, although this probably needs additional testing.

## Testing

The changes seemed minimal enough that a compile test would be
sufficient.

## Migration guide

Image formats that previously weren't feature-gated are now
feature-gated, meaning they will have to be enabled if you use them:

* `avif`
* `ff` (Farbfeld)
* `gif`
* `ico`
* `tiff`

Additionally, the `qoi` feature has been added to support loading QOI
format images.

Previously, these formats appeared in the enum by default, but weren't
actually enabled via the `image` crate, potentially resulting in weird
bugs. Now, you should be able to add these features to your projects to
support them properly.
This commit is contained in:
Clar Fon 2024-10-07 12:37:45 -04:00 committed by GitHub
parent 0a1d60f3b0
commit 8adc9e9d6e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 394 additions and 149 deletions

View file

@ -100,39 +100,40 @@ unused_qualifications = "warn"
[features]
default = [
"android-game-activity",
"android-game-activity",
"android_shared_stdcxx",
"animation",
"bevy_asset",
"bevy_state",
"bevy_audio",
"bevy_color",
"bevy_gilrs",
"bevy_scene",
"bevy_winit",
"bevy_core_pipeline",
"bevy_gilrs",
"bevy_gizmos",
"bevy_gltf",
"bevy_pbr",
"bevy_picking",
"bevy_sprite_picking_backend",
"bevy_ui_picking_backend",
"bevy_gltf",
"bevy_remote",
"bevy_render",
"bevy_scene",
"bevy_sprite",
"bevy_sprite_picking_backend",
"bevy_state",
"bevy_text",
"bevy_ui",
"bevy_remote",
"bevy_ui_picking_backend",
"bevy_winit",
"custom_cursor",
"default_font",
"hdr",
"multi_threaded",
"png",
"hdr",
"vorbis",
"x11",
"bevy_gizmos",
"android_shared_stdcxx",
"tonemapping_luts",
"smaa_luts",
"default_font",
"webgl2",
"sysinfo_plugin",
"android-game-activity",
"custom_cursor",
"tonemapping_luts",
"vorbis",
"webgl2",
"x11",
]
# Provides an implementation for picking sprites
@ -242,39 +243,57 @@ trace_tracy_memory = [
# Tracing support
trace = ["bevy_internal/trace"]
# EXR image format support
exr = ["bevy_internal/exr"]
# HDR image format support
hdr = ["bevy_internal/hdr"]
# PNG image format support
png = ["bevy_internal/png"]
# TGA image format support
tga = ["bevy_internal/tga"]
# JPEG image format support
jpeg = ["bevy_internal/jpeg"]
# BMP image format support
bmp = ["bevy_internal/bmp"]
# WebP image format support
webp = ["bevy_internal/webp"]
# AVIF image format support
avif = ["bevy_internal/avif"]
# Basis Universal compressed texture support
basis-universal = ["bevy_internal/basis-universal"]
# BMP image format support
bmp = ["bevy_internal/bmp"]
# DDS compressed texture support
dds = ["bevy_internal/dds"]
# EXR image format support
exr = ["bevy_internal/exr"]
# Farbfeld image format support
ff = ["bevy_internal/ff"]
# GIF image format support
gif = ["bevy_internal/gif"]
# HDR image format support
hdr = ["bevy_internal/hdr"]
# KTX2 compressed texture support
ktx2 = ["bevy_internal/ktx2"]
# ICO image format support
ico = ["bevy_internal/ico"]
# JPEG image format support
jpeg = ["bevy_internal/jpeg"]
# PNG image format support
png = ["bevy_internal/png"]
# PNM image format support, includes pam, pbm, pgm and ppm
pnm = ["bevy_internal/pnm"]
# QOI image format support
qoi = ["bevy_internal/qoi"]
# TGA image format support
tga = ["bevy_internal/tga"]
# TIFF image format support
tiff = ["bevy_internal/tiff"]
# WebP image format support
webp = ["bevy_internal/webp"]
# For KTX2 supercompression
zlib = ["bevy_internal/zlib"]

View file

@ -13,12 +13,12 @@ license = "MIT OR Apache-2.0"
keywords = ["bevy"]
[features]
dds = ["bevy_render/dds"]
dds = ["bevy_render/dds", "bevy_image/dds"]
trace = []
webgl = []
webgpu = []
tonemapping_luts = ["bevy_render/ktx2", "bevy_render/zstd"]
smaa_luts = ["bevy_render/ktx2", "bevy_render/zstd"]
tonemapping_luts = ["bevy_render/ktx2", "bevy_image/ktx2", "bevy_image/zstd"]
smaa_luts = ["bevy_render/ktx2", "bevy_image/ktx2", "bevy_image/zstd"]
[dependencies]
# bevy
@ -28,6 +28,7 @@ bevy_core = { path = "../bevy_core", version = "0.15.0-dev" }
bevy_color = { path = "../bevy_color", version = "0.15.0-dev" }
bevy_derive = { path = "../bevy_derive", version = "0.15.0-dev" }
bevy_ecs = { path = "../bevy_ecs", version = "0.15.0-dev" }
bevy_image = { path = "../bevy_image", version = "0.15.0-dev" }
bevy_reflect = { path = "../bevy_reflect", version = "0.15.0-dev" }
bevy_render = { path = "../bevy_render", version = "0.15.0-dev" }
bevy_transform = { path = "../bevy_transform", version = "0.15.0-dev" }

View file

@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0"
keywords = ["bevy"]
[features]
dds = ["bevy_render/dds", "bevy_core_pipeline/dds"]
dds = ["bevy_render/dds", "bevy_image/dds", "bevy_core_pipeline/dds"]
pbr_transmission_textures = ["bevy_pbr/pbr_transmission_textures"]
pbr_multi_layer_material_textures = [
"bevy_pbr/pbr_multi_layer_material_textures",
@ -26,6 +26,7 @@ bevy_core = { path = "../bevy_core", version = "0.15.0-dev" }
bevy_core_pipeline = { path = "../bevy_core_pipeline", version = "0.15.0-dev" }
bevy_ecs = { path = "../bevy_ecs", version = "0.15.0-dev" }
bevy_hierarchy = { path = "../bevy_hierarchy", version = "0.15.0-dev" }
bevy_image = { path = "../bevy_image", version = "0.15.0-dev" }
bevy_math = { path = "../bevy_math", version = "0.15.0-dev" }
bevy_pbr = { path = "../bevy_pbr", version = "0.15.0-dev" }
bevy_reflect = { path = "../bevy_reflect", version = "0.15.0-dev", features = [

View file

@ -9,15 +9,24 @@ license = "MIT OR Apache-2.0"
keywords = ["bevy"]
[features]
png = ["image/png"]
exr = ["image/exr"]
hdr = ["image/hdr"]
tga = ["image/tga"]
jpeg = ["image/jpeg"]
# Image formats
avif = ["image/avif"]
basis-universal = ["dep:basis-universal"]
bmp = ["image/bmp"]
webp = ["image/webp"]
dds = ["ddsfile"]
exr = ["image/exr"]
ff = ["image/ff"]
gif = ["image/gif"]
hdr = ["image/hdr"]
ktx2 = ["dep:ktx2"]
ico = ["image/ico"]
jpeg = ["image/jpeg"]
png = ["image/png"]
pnm = ["image/pnm"]
qoi = ["image/qoi"]
tga = ["image/tga"]
tiff = ["image/tiff"]
webp = ["image/webp"]
# For ktx2 supercompression
zlib = ["flate2"]

View file

@ -29,6 +29,7 @@ pub const SAMPLER_ASSET_INDEX: u64 = 1;
#[derive(Debug, Serialize, Deserialize, Copy, Clone)]
pub enum ImageFormat {
#[cfg(feature = "avif")]
Avif,
#[cfg(feature = "basis-universal")]
Basis,
@ -36,12 +37,15 @@ pub enum ImageFormat {
Bmp,
#[cfg(feature = "dds")]
Dds,
#[cfg(feature = "ff")]
Farbfeld,
#[cfg(feature = "gif")]
Gif,
#[cfg(feature = "exr")]
OpenExr,
#[cfg(feature = "hdr")]
Hdr,
#[cfg(feature = "ico")]
Ico,
#[cfg(feature = "jpeg")]
Jpeg,
@ -51,8 +55,11 @@ pub enum ImageFormat {
Png,
#[cfg(feature = "pnm")]
Pnm,
#[cfg(feature = "qoi")]
Qoi,
#[cfg(feature = "tga")]
Tga,
#[cfg(feature = "tiff")]
Tiff,
#[cfg(feature = "webp")]
WebP,
@ -71,24 +78,261 @@ macro_rules! feature_gate {
}
impl ImageFormat {
/// Number of image formats, used for computing other constants.
const COUNT: usize = {
let mut count = 0;
#[cfg(feature = "avif")]
{
count += 1;
}
#[cfg(feature = "basis-universal")]
{
count += 1;
}
#[cfg(feature = "bmp")]
{
count += 1;
}
#[cfg(feature = "dds")]
{
count += 1;
}
#[cfg(feature = "ff")]
{
count += 1;
}
#[cfg(feature = "gif")]
{
count += 1;
}
#[cfg(feature = "exr")]
{
count += 1;
}
#[cfg(feature = "hdr")]
{
count += 1;
}
#[cfg(feature = "ico")]
{
count += 1;
}
#[cfg(feature = "jpeg")]
{
count += 1;
}
#[cfg(feature = "ktx2")]
{
count += 1;
}
#[cfg(feature = "pnm")]
{
count += 1;
}
#[cfg(feature = "png")]
{
count += 1;
}
#[cfg(feature = "qoi")]
{
count += 1;
}
#[cfg(feature = "tga")]
{
count += 1;
}
#[cfg(feature = "tiff")]
{
count += 1;
}
#[cfg(feature = "webp")]
{
count += 1;
}
count
};
/// Full list of supported formats.
pub const SUPPORTED: &'static [ImageFormat] = &[
#[cfg(feature = "avif")]
ImageFormat::Avif,
#[cfg(feature = "basis-universal")]
ImageFormat::Basis,
#[cfg(feature = "bmp")]
ImageFormat::Bmp,
#[cfg(feature = "dds")]
ImageFormat::Dds,
#[cfg(feature = "ff")]
ImageFormat::Farbfeld,
#[cfg(feature = "gif")]
ImageFormat::Gif,
#[cfg(feature = "exr")]
ImageFormat::OpenExr,
#[cfg(feature = "hdr")]
ImageFormat::Hdr,
#[cfg(feature = "ico")]
ImageFormat::Ico,
#[cfg(feature = "jpeg")]
ImageFormat::Jpeg,
#[cfg(feature = "ktx2")]
ImageFormat::Ktx2,
#[cfg(feature = "png")]
ImageFormat::Png,
#[cfg(feature = "pnm")]
ImageFormat::Pnm,
#[cfg(feature = "qoi")]
ImageFormat::Qoi,
#[cfg(feature = "tga")]
ImageFormat::Tga,
#[cfg(feature = "tiff")]
ImageFormat::Tiff,
#[cfg(feature = "webp")]
ImageFormat::WebP,
];
/// Total count of file extensions, for computing supported file extensions list.
const COUNT_FILE_EXTENSIONS: usize = {
let mut count = 0;
let mut idx = 0;
while idx < ImageFormat::COUNT {
count += ImageFormat::SUPPORTED[idx].to_file_extensions().len();
idx += 1;
}
count
};
/// Gets the list of file extensions for all formats.
pub const SUPPORTED_FILE_EXTENSIONS: &'static [&'static str] = &{
let mut exts = [""; ImageFormat::COUNT_FILE_EXTENSIONS];
let mut ext_idx = 0;
let mut fmt_idx = 0;
while fmt_idx < ImageFormat::COUNT {
let mut off = 0;
let fmt_exts = ImageFormat::SUPPORTED[fmt_idx].to_file_extensions();
while off < fmt_exts.len() {
exts[ext_idx] = fmt_exts[off];
off += 1;
ext_idx += 1;
}
fmt_idx += 1;
}
exts
};
/// Gets the file extensions for a given format.
pub const fn to_file_extensions(&self) -> &'static [&'static str] {
match self {
#[cfg(feature = "avif")]
ImageFormat::Avif => &["avif"],
#[cfg(feature = "basis-universal")]
ImageFormat::Basis => &["basis"],
#[cfg(feature = "bmp")]
ImageFormat::Bmp => &["bmp"],
#[cfg(feature = "dds")]
ImageFormat::Dds => &["dds"],
#[cfg(feature = "ff")]
ImageFormat::Farbfeld => &["ff", "farbfeld"],
#[cfg(feature = "gif")]
ImageFormat::Gif => &["gif"],
#[cfg(feature = "exr")]
ImageFormat::OpenExr => &["exr"],
#[cfg(feature = "hdr")]
ImageFormat::Hdr => &["hdr"],
#[cfg(feature = "ico")]
ImageFormat::Ico => &["ico"],
#[cfg(feature = "jpeg")]
ImageFormat::Jpeg => &["jpg", "jpeg"],
#[cfg(feature = "ktx2")]
ImageFormat::Ktx2 => &["ktx2"],
#[cfg(feature = "pnm")]
ImageFormat::Pnm => &["pam", "pbm", "pgm", "ppm"],
#[cfg(feature = "png")]
ImageFormat::Png => &["png"],
#[cfg(feature = "qoi")]
ImageFormat::Qoi => &["qoi"],
#[cfg(feature = "tga")]
ImageFormat::Tga => &["tga"],
#[cfg(feature = "tiff")]
ImageFormat::Tiff => &["tif", "tiff"],
#[cfg(feature = "webp")]
ImageFormat::WebP => &["webp"],
// FIXME: https://github.com/rust-lang/rust/issues/129031
#[allow(unreachable_patterns)]
_ => &[],
}
}
/// Gets the MIME types for a given format.
///
/// If a format doesn't have any dedicated MIME types, this list will be empty.
pub const fn to_mime_types(&self) -> &'static [&'static str] {
match self {
#[cfg(feature = "avif")]
ImageFormat::Avif => &["image/avif"],
#[cfg(feature = "basis-universal")]
ImageFormat::Basis => &["image/basis", "image/x-basis"],
#[cfg(feature = "bmp")]
ImageFormat::Bmp => &["image/bmp", "image/x-bmp"],
#[cfg(feature = "dds")]
ImageFormat::Dds => &["image/vnd-ms.dds"],
#[cfg(feature = "hdr")]
ImageFormat::Hdr => &["image/vnd.radiance"],
#[cfg(feature = "gif")]
ImageFormat::Gif => &["image/gif"],
#[cfg(feature = "ff")]
ImageFormat::Farbfeld => &[],
#[cfg(feature = "ico")]
ImageFormat::Ico => &["image/x-icon"],
#[cfg(feature = "jpeg")]
ImageFormat::Jpeg => &["image/jpeg"],
#[cfg(feature = "ktx2")]
ImageFormat::Ktx2 => &["image/ktx2"],
#[cfg(feature = "png")]
ImageFormat::Png => &["image/png"],
#[cfg(feature = "qoi")]
ImageFormat::Qoi => &["image/qoi", "image/x-qoi"],
#[cfg(feature = "exr")]
ImageFormat::OpenExr => &["image/x-exr"],
#[cfg(feature = "pnm")]
ImageFormat::Pnm => &[
"image/x-portable-bitmap",
"image/x-portable-graymap",
"image/x-portable-pixmap",
"image/x-portable-anymap",
],
#[cfg(feature = "tga")]
ImageFormat::Tga => &["image/x-targa", "image/x-tga"],
#[cfg(feature = "tiff")]
ImageFormat::Tiff => &["image/tiff"],
#[cfg(feature = "webp")]
ImageFormat::WebP => &["image/webp"],
// FIXME: https://github.com/rust-lang/rust/issues/129031
#[allow(unreachable_patterns)]
_ => &[],
}
}
pub fn from_mime_type(mime_type: &str) -> Option<Self> {
Some(match mime_type.to_ascii_lowercase().as_str() {
"image/avif" => ImageFormat::Avif,
// note: farbfeld does not have a MIME type
"image/avif" => feature_gate!("avif", Avif),
"image/basis" | "image/x-basis" => feature_gate!("basis-universal", Basis),
"image/bmp" | "image/x-bmp" => feature_gate!("bmp", Bmp),
"image/vnd-ms.dds" => feature_gate!("dds", Dds),
"image/vnd.radiance" => feature_gate!("hdr", Hdr),
"image/gif" => ImageFormat::Gif,
"image/x-icon" => ImageFormat::Ico,
"image/gif" => feature_gate!("gif", Gif),
"image/x-icon" => feature_gate!("ico", Ico),
"image/jpeg" => feature_gate!("jpeg", Jpeg),
"image/ktx2" => feature_gate!("ktx2", Ktx2),
"image/png" => feature_gate!("png", Png),
"image/qoi" | "image/x-qoi" => feature_gate!("qoi", Qoi),
"image/x-exr" => feature_gate!("exr", OpenExr),
"image/x-portable-bitmap"
| "image/x-portable-graymap"
| "image/x-portable-pixmap"
| "image/x-portable-anymap" => feature_gate!("pnm", Pnm),
"image/x-targa" | "image/x-tga" => feature_gate!("tga", Tga),
"image/tiff" => ImageFormat::Tiff,
"image/tiff" => feature_gate!("tiff", Tiff),
"image/webp" => feature_gate!("webp", WebP),
_ => return None,
})
@ -96,21 +340,22 @@ impl ImageFormat {
pub fn from_extension(extension: &str) -> Option<Self> {
Some(match extension.to_ascii_lowercase().as_str() {
"avif" => ImageFormat::Avif,
"avif" => feature_gate!("avif", Avif),
"basis" => feature_gate!("basis-universal", Basis),
"bmp" => feature_gate!("bmp", Bmp),
"dds" => feature_gate!("dds", Dds),
"ff" | "farbfeld" => ImageFormat::Farbfeld,
"gif" => ImageFormat::Gif,
"ff" | "farbfeld" => feature_gate!("ff", Farbfeld),
"gif" => feature_gate!("gif", Gif),
"exr" => feature_gate!("exr", OpenExr),
"hdr" => feature_gate!("hdr", Hdr),
"ico" => ImageFormat::Ico,
"ico" => feature_gate!("ico", Ico),
"jpg" | "jpeg" => feature_gate!("jpeg", Jpeg),
"ktx2" => feature_gate!("ktx2", Ktx2),
"pbm" | "pam" | "ppm" | "pgm" => feature_gate!("pnm", Pnm),
"pam" | "pbm" | "pgm" | "ppm" => feature_gate!("pnm", Pnm),
"png" => feature_gate!("png", Png),
"qoi" => feature_gate!("qoi", Qoi),
"tga" => feature_gate!("tga", Tga),
"tif" | "tiff" => ImageFormat::Tiff,
"tif" | "tiff" => feature_gate!("tiff", Tiff),
"webp" => feature_gate!("webp", WebP),
_ => return None,
})
@ -118,17 +363,21 @@ impl ImageFormat {
pub fn as_image_crate_format(&self) -> Option<image::ImageFormat> {
Some(match self {
#[cfg(feature = "avif")]
ImageFormat::Avif => image::ImageFormat::Avif,
#[cfg(feature = "bmp")]
ImageFormat::Bmp => image::ImageFormat::Bmp,
#[cfg(feature = "dds")]
ImageFormat::Dds => image::ImageFormat::Dds,
#[cfg(feature = "ff")]
ImageFormat::Farbfeld => image::ImageFormat::Farbfeld,
#[cfg(feature = "gif")]
ImageFormat::Gif => image::ImageFormat::Gif,
#[cfg(feature = "exr")]
ImageFormat::OpenExr => image::ImageFormat::OpenExr,
#[cfg(feature = "hdr")]
ImageFormat::Hdr => image::ImageFormat::Hdr,
#[cfg(feature = "ico")]
ImageFormat::Ico => image::ImageFormat::Ico,
#[cfg(feature = "jpeg")]
ImageFormat::Jpeg => image::ImageFormat::Jpeg,
@ -136,8 +385,11 @@ impl ImageFormat {
ImageFormat::Png => image::ImageFormat::Png,
#[cfg(feature = "pnm")]
ImageFormat::Pnm => image::ImageFormat::Pnm,
#[cfg(feature = "qoi")]
ImageFormat::Qoi => image::ImageFormat::Qoi,
#[cfg(feature = "tga")]
ImageFormat::Tga => image::ImageFormat::Tga,
#[cfg(feature = "tiff")]
ImageFormat::Tiff => image::ImageFormat::Tiff,
#[cfg(feature = "webp")]
ImageFormat::WebP => image::ImageFormat::WebP,
@ -145,24 +397,28 @@ impl ImageFormat {
ImageFormat::Basis => return None,
#[cfg(feature = "ktx2")]
ImageFormat::Ktx2 => return None,
// FIXME: https://github.com/rust-lang/rust/issues/129031
#[allow(unreachable_patterns)]
_ => return None,
})
}
pub fn from_image_crate_format(format: image::ImageFormat) -> Option<ImageFormat> {
Some(match format {
image::ImageFormat::Avif => ImageFormat::Avif,
image::ImageFormat::Avif => feature_gate!("avif", Avif),
image::ImageFormat::Bmp => feature_gate!("bmp", Bmp),
image::ImageFormat::Dds => feature_gate!("dds", Dds),
image::ImageFormat::Farbfeld => ImageFormat::Farbfeld,
image::ImageFormat::Gif => ImageFormat::Gif,
image::ImageFormat::Farbfeld => feature_gate!("ff", Farbfeld),
image::ImageFormat::Gif => feature_gate!("gif", Gif),
image::ImageFormat::OpenExr => feature_gate!("exr", OpenExr),
image::ImageFormat::Hdr => feature_gate!("hdr", Hdr),
image::ImageFormat::Ico => ImageFormat::Ico,
image::ImageFormat::Ico => feature_gate!("ico", Ico),
image::ImageFormat::Jpeg => feature_gate!("jpeg", Jpeg),
image::ImageFormat::Png => feature_gate!("png", Png),
image::ImageFormat::Pnm => feature_gate!("pnm", Pnm),
image::ImageFormat::Qoi => feature_gate!("qoi", Qoi),
image::ImageFormat::Tga => feature_gate!("tga", Tga),
image::ImageFormat::Tiff => ImageFormat::Tiff,
image::ImageFormat::Tiff => feature_gate!("tiff", Tiff),
image::ImageFormat::WebP => feature_gate!("webp", WebP),
_ => return None,
})

View file

@ -28,21 +28,35 @@ detailed_trace = ["bevy_utils/detailed_trace"]
sysinfo_plugin = ["bevy_diagnostic/sysinfo_plugin"]
# Image format support for texture loading (PNG and HDR are enabled by default)
exr = ["bevy_render/exr"]
hdr = ["bevy_render/hdr"]
png = ["bevy_render/png"]
tga = ["bevy_render/tga"]
jpeg = ["bevy_render/jpeg"]
bmp = ["bevy_render/bmp"]
webp = ["bevy_render/webp"]
basis-universal = ["bevy_render/basis-universal"]
dds = ["bevy_render/dds", "bevy_core_pipeline/dds", "bevy_gltf/dds"]
pnm = ["bevy_render/pnm"]
ktx2 = ["bevy_render/ktx2"]
# Texture formats that have specific rendering support (HDR enabled by default)
basis-universal = ["bevy_image/basis-universal", "bevy_render/basis-universal"]
dds = [
"bevy_image/dds",
"bevy_render/dds",
"bevy_core_pipeline/dds",
"bevy_gltf/dds",
]
exr = ["bevy_image/exr", "bevy_render/exr"]
hdr = ["bevy_image/hdr", "bevy_render/hdr"]
ktx2 = ["bevy_image/ktx2", "bevy_render/ktx2"]
# For ktx2 supercompression
zlib = ["bevy_render/zlib"]
zstd = ["bevy_render/zstd"]
zlib = ["bevy_image/zlib"]
zstd = ["bevy_image/zstd"]
# Image format support (PNG enabled by default)
avif = ["bevy_image/avif"]
bmp = ["bevy_image/bmp"]
ff = ["bevy_image/ff"]
gif = ["bevy_image/gif"]
ico = ["bevy_image/ico"]
jpeg = ["bevy_image/jpeg"]
png = ["bevy_image/png"]
pnm = ["bevy_image/pnm"]
qoi = ["bevy_image/qoi"]
tga = ["bevy_image/tga"]
tiff = ["bevy_image/tiff"]
webp = ["bevy_image/webp"]
# Enable SPIR-V passthrough
spirv_shader_passthrough = ["bevy_render/spirv_shader_passthrough"]
@ -258,6 +272,7 @@ bevy_dev_tools = { path = "../bevy_dev_tools", optional = true, version = "0.15.
bevy_gilrs = { path = "../bevy_gilrs", optional = true, version = "0.15.0-dev" }
bevy_gizmos = { path = "../bevy_gizmos", optional = true, version = "0.15.0-dev", default-features = false }
bevy_gltf = { path = "../bevy_gltf", optional = true, version = "0.15.0-dev" }
bevy_image = { path = "../bevy_image", optional = true, version = "0.15.0-dev" }
bevy_pbr = { path = "../bevy_pbr", optional = true, version = "0.15.0-dev" }
bevy_picking = { path = "../bevy_picking", optional = true, version = "0.15.0-dev" }
bevy_remote = { path = "../bevy_remote", optional = true, version = "0.15.0-dev" }

View file

@ -9,31 +9,18 @@ license = "MIT OR Apache-2.0"
keywords = ["bevy"]
[features]
png = ["image/png", "bevy_image/png"]
exr = ["image/exr", "bevy_image/exr"]
hdr = ["image/hdr", "bevy_image/hdr"]
tga = ["image/tga", "bevy_image/tga"]
jpeg = ["image/jpeg", "bevy_image/jpeg"]
bmp = ["image/bmp", "bevy_image/bmp"]
webp = ["image/webp", "bevy_image/webp"]
dds = ["ddsfile", "bevy_image/dds"]
pnm = ["image/pnm", "bevy_image/pnm"]
ddsfile = ["bevy_image/ddsfile"]
ktx2 = ["dep:ktx2", "bevy_image/ktx2"]
flate2 = ["bevy_image/flate2"]
ruzstd = ["bevy_image/ruzstd"]
# Texture formats (require more than just image support)
basis-universal = ["dep:basis-universal", "bevy_image/basis-universal"]
dds = ["bevy_image/dds"]
exr = ["bevy_image/exr"]
hdr = ["bevy_image/hdr"]
ktx2 = ["dep:ktx2", "bevy_image/ktx2"]
multi_threaded = ["bevy_tasks/multi_threaded"]
shader_format_glsl = ["naga/glsl-in", "naga/wgsl-out", "naga_oil/glsl"]
shader_format_spirv = ["wgpu/spirv", "naga/spv-in", "naga/spv-out"]
# For ktx2 supercompression
zlib = ["flate2", "bevy_image/zlib"]
zstd = ["ruzstd", "bevy_image/zstd"]
# Enable SPIR-V shader passthrough
spirv_shader_passthrough = []

View file

@ -17,35 +17,6 @@ pub struct ImageLoader {
supported_compressed_formats: CompressedImageFormats,
}
pub(crate) const IMG_FILE_EXTENSIONS: &[&str] = &[
#[cfg(feature = "basis-universal")]
"basis",
#[cfg(feature = "bmp")]
"bmp",
#[cfg(feature = "png")]
"png",
#[cfg(feature = "dds")]
"dds",
#[cfg(feature = "tga")]
"tga",
#[cfg(feature = "jpeg")]
"jpg",
#[cfg(feature = "jpeg")]
"jpeg",
#[cfg(feature = "ktx2")]
"ktx2",
#[cfg(feature = "webp")]
"webp",
#[cfg(feature = "pnm")]
"pam",
#[cfg(feature = "pnm")]
"pbm",
#[cfg(feature = "pnm")]
"pgm",
#[cfg(feature = "pnm")]
"ppm",
];
#[derive(Serialize, Deserialize, Default, Debug)]
pub enum ImageFormatSetting {
#[default]
@ -131,7 +102,7 @@ impl AssetLoader for ImageLoader {
}
fn extensions(&self) -> &[&str] {
IMG_FILE_EXTENSIONS
ImageFormat::SUPPORTED_FILE_EXTENSIONS
}
}

View file

@ -114,33 +114,13 @@ impl Plugin for ImagePlugin {
);
}
#[cfg(any(
feature = "png",
feature = "dds",
feature = "tga",
feature = "jpeg",
feature = "bmp",
feature = "basis-universal",
feature = "ktx2",
feature = "webp",
feature = "pnm"
))]
app.preregister_asset_loader::<ImageLoader>(IMG_FILE_EXTENSIONS);
if !ImageFormat::SUPPORTED_FILE_EXTENSIONS.is_empty() {
app.preregister_asset_loader::<ImageLoader>(ImageFormat::SUPPORTED_FILE_EXTENSIONS);
}
}
fn finish(&self, app: &mut App) {
#[cfg(any(
feature = "png",
feature = "dds",
feature = "tga",
feature = "jpeg",
feature = "bmp",
feature = "basis-universal",
feature = "ktx2",
feature = "webp",
feature = "pnm"
))]
{
if !ImageFormat::SUPPORTED.is_empty() {
app.init_asset_loader::<ImageLoader>();
}

View file

@ -56,6 +56,7 @@ The default feature set enables most of the expected features of a game engine,
|android-native-activity|Android NativeActivity support. Legacy, should be avoided for most new Android games.|
|asset_processor|Enables the built-in asset processor for processed assets.|
|async-io|Use async-io's implementation of block_on instead of futures-lite's implementation. This is preferred if your application uses async-io.|
|avif|AVIF image format support|
|basis-universal|Basis Universal compressed texture support|
|bevy_ci_testing|Enable systems that allow for automated testing on CI|
|bevy_debug_stepping|Enable stepping-based debugging of Bevy systems|
@ -67,9 +68,12 @@ The default feature set enables most of the expected features of a game engine,
|dynamic_linking|Force dynamic linking, which improves iterative compile times|
|embedded_watcher|Enables watching in memory asset providers for Bevy Asset hot-reloading|
|exr|EXR image format support|
|ff|Farbfeld image format support|
|file_watcher|Enables watching the filesystem for Bevy Asset hot-reloading|
|flac|FLAC audio format support|
|gif|GIF image format support|
|glam_assert|Enable assertions to check the validity of parameters passed to glam|
|ico|ICO image format support|
|ios_simulator|Enable support for the ios_simulator by downgrading some rendering capabilities|
|jpeg|JPEG image format support|
|meshlet|Enables the meshlet renderer for dense high-poly scenes (experimental)|
@ -80,6 +84,7 @@ The default feature set enables most of the expected features of a game engine,
|pbr_multi_layer_material_textures|Enable support for multi-layer material textures in the `StandardMaterial`, at the risk of blowing past the global, per-shader texture limit on older/lower-end GPUs|
|pbr_transmission_textures|Enable support for transmission-related textures in the `StandardMaterial`, at the risk of blowing past the global, per-shader texture limit on older/lower-end GPUs|
|pnm|PNM image format support, includes pam, pbm, pgm and ppm|
|qoi|QOI image format support|
|reflect_functions|Enable function reflection|
|serialize|Enable serialization support through serde|
|shader_format_glsl|Enable support for shaders in GLSL|
@ -92,6 +97,7 @@ The default feature set enables most of the expected features of a game engine,
|symphonia-vorbis|OGG/VORBIS audio format support (through symphonia)|
|symphonia-wav|WAV audio format support (through symphonia)|
|tga|TGA image format support|
|tiff|TIFF image format support|
|trace|Tracing support|
|trace_chrome|Tracing support, saving a file in Chrome Tracing format|
|trace_tracy|Tracing support, exposing a port for Tracy|