Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better validation of images for potential UHD feature. #47

Merged
merged 1 commit into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions examples/wasm-modules/graphics/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ pub mod handles;
pub mod graphics_mt {
pub use ::graphics::graphics_mt::*;
}
pub mod image {
pub use ::graphics::image::*;
}

pub mod quad_container {
pub use ::graphics::quad_container::*;
}
Expand Down
33 changes: 25 additions & 8 deletions game/client-containers/src/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,18 @@ use either::Either;
use game_interface::types::resource_key::ResourceKey;
use graphics::{
graphics::graphics::Graphics, graphics_mt::GraphicsMultiThreaded,
handles::texture::texture::GraphicsTextureHandle, image::texture_2d_to_3d,
handles::texture::texture::GraphicsTextureHandle,
};
use graphics_types::{
commands::TexFlags,
types::{GraphicsBackendMemory, GraphicsMemoryAllocationType},
};
use hashlink::LinkedHashMap;
use hiarc::Hiarc;
use image::png::{is_png_image_valid, load_png_image, PngResultPersistent};
use image::{
png::{is_png_image_valid, load_png_image_as_rgba, PngResultPersistent, PngValidatorOptions},
utils::texture_2d_to_3d,
};
use log::info;
use sound::{
ogg_vorbis::verify_ogg_vorbis, scene_object::SceneObject, sound::SoundManager,
Expand Down Expand Up @@ -415,10 +418,20 @@ where
}

/// Verifies a resource, prints warnings on error
fn verify_resource(file_ty: &str, file_name: &str, file: &[u8]) -> bool {
fn verify_resource(file_ty: &str, file_name: &str, file: &[u8], allow_hq_assets: bool) -> bool {
match file_ty {
"png" => {
if let Err(err) = is_png_image_valid(file, Default::default()) {
if let Err(err) = is_png_image_valid(
file,
if allow_hq_assets {
PngValidatorOptions {
max_width: 4096.try_into().unwrap(),
max_height: 4096.try_into().unwrap(),
}
} else {
Default::default()
},
) {
log::warn!(
"downloaded image resource (png) {}\
is not a valid png file: {}",
Expand Down Expand Up @@ -523,6 +536,8 @@ where
game_server_http: Option<Url>,
resource_http_download: HttpIndexAndUrl,
) -> anyhow::Result<ContainerLoadedItem> {
let allow_hq_assets = false;

let read_tar = |file: &[u8]| {
let mut file = tar::Archive::new(std::io::Cursor::new(file));
match file.entries() {
Expand Down Expand Up @@ -637,6 +652,7 @@ where
name.extension().and_then(|s| s.to_str()).unwrap_or(""),
name.file_stem().and_then(|s| s.to_str()).unwrap_or(""),
file,
allow_hq_assets,
) {
verified = false;
break;
Expand All @@ -663,7 +679,7 @@ where
}) {
let _g = http_download_tasks.acquire().await?;
if let Ok(file) = http.download_binary(game_server_http, &hash).await {
if Self::verify_resource("png", &name, &file) {
if Self::verify_resource("png", &name, &file, allow_hq_assets) {
save_to_disk(&name, &file).await;
files = Some(ContainerLoadedItem::SingleFile(file.to_vec()));
}
Expand Down Expand Up @@ -799,6 +815,7 @@ where
name.extension().and_then(|s| s.to_str()).unwrap_or(""),
name.file_stem().and_then(|s| s.to_str()).unwrap_or(""),
file,
allow_hq_assets,
) {
verified = false;
break;
Expand All @@ -816,7 +833,7 @@ where
false
}
} else if ty == "png" {
if Self::verify_resource("png", &name, &file) {
if Self::verify_resource("png", &name, &file, allow_hq_assets) {
files = Some(ContainerLoadedItem::SingleFile(file.to_vec()));
true
} else {
Expand Down Expand Up @@ -1372,7 +1389,7 @@ pub fn load_file_part_as_png_ex(
allow_default,
)?;
let mut img_data = Vec::<u8>::new();
let part_img = load_png_image(file.data, |width, height, bytes_per_pixel| {
let part_img = load_png_image_as_rgba(file.data, |width, height, bytes_per_pixel| {
img_data = vec![0; width * height * bytes_per_pixel];
&mut img_data
})?;
Expand Down Expand Up @@ -1548,7 +1565,7 @@ pub fn load_file_part_as_png_and_convert_3d(
true,
)?;
let mut img_data = Vec::<u8>::new();
let part_img = load_png_image(file.data, |width, height, bytes_per_pixel| {
let part_img = load_png_image_as_rgba(file.data, |width, height, bytes_per_pixel| {
img_data = vec![0; width * height * bytes_per_pixel];
&mut img_data
})?;
Expand Down
2 changes: 1 addition & 1 deletion game/client-containers/src/emoticons.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl LoadEmoticons {
fn load_full(files: &mut FxHashMap<PathBuf, Vec<u8>>, file: Vec<u8>) -> anyhow::Result<()> {
let mut mem: Vec<u8> = Default::default();
let img: image::png::PngResult<'_> =
image::png::load_png_image(&file, |width, height, bytes_per_pixel| {
image::png::load_png_image_as_rgba(&file, |width, height, bytes_per_pixel| {
mem.resize(width * height * bytes_per_pixel, Default::default());
&mut mem
})?;
Expand Down
2 changes: 1 addition & 1 deletion game/client-containers/src/hud.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ impl LoadHud {
fn load_full(files: &mut FxHashMap<PathBuf, Vec<u8>>, file: Vec<u8>) -> anyhow::Result<()> {
let mut mem: Vec<u8> = Default::default();
let img: image::png::PngResult<'_> =
image::png::load_png_image(&file, |width, height, bytes_per_pixel| {
image::png::load_png_image_as_rgba(&file, |width, height, bytes_per_pixel| {
mem.resize(width * height * bytes_per_pixel, Default::default());
&mut mem
})?;
Expand Down
2 changes: 1 addition & 1 deletion game/client-containers/src/particles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl LoadParticle {
fn load_full(files: &mut FxHashMap<PathBuf, Vec<u8>>, file: Vec<u8>) -> anyhow::Result<()> {
let mut mem: Vec<u8> = Default::default();
let img: image::png::PngResult<'_> =
image::png::load_png_image(&file, |width, height, bytes_per_pixel| {
image::png::load_png_image_as_rgba(&file, |width, height, bytes_per_pixel| {
mem.resize(width * height * bytes_per_pixel, Default::default());
&mut mem
})?;
Expand Down
2 changes: 1 addition & 1 deletion game/client-containers/src/skins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ impl LoadSkinTexturesData {
) -> anyhow::Result<()> {
let mut mem: Vec<u8> = Default::default();
let img: image::png::PngResult<'_> =
image::png::load_png_image(&file, |width, height, bytes_per_pixel| {
image::png::load_png_image_as_rgba(&file, |width, height, bytes_per_pixel| {
mem.resize(width * height * bytes_per_pixel, Default::default());
&mut mem
})?;
Expand Down
44 changes: 33 additions & 11 deletions game/client-render-base/src/map/render_map_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@ use graphics::{
stream::stream::GraphicsStreamHandle,
texture::texture::{GraphicsTextureHandle, TextureContainer, TextureContainer2dArray},
},
image::{highest_bit, resize, texture_2d_to_3d},
};
use graphics_types::{commands::TexFlags, types::GraphicsMemoryAllocationType};
use image::png::{is_png_image_valid, load_png_image};
use image::{
png::{is_png_image_valid, load_png_image_as_rgba, resize_rgba, PngValidatorOptions},
utils::{highest_bit, texture_2d_to_3d},
};
use map::map::Map;
use math::math::vector::vec2;
use rayon::iter::{IntoParallelIterator, ParallelIterator};
Expand Down Expand Up @@ -195,6 +197,7 @@ impl RenderMapLoading {
file_ty.as_str(),
file_name.as_str(),
&file,
load_hq_assets,
)?;
let file_path: &Path = read_file_path.as_ref();
if let Some(dir) = file_path.parent() {
Expand Down Expand Up @@ -254,19 +257,23 @@ impl RenderMapLoading {
|| convert_height == 0
|| (convert_height % 16) != 0
{
// TODO sys.log("image").msg("3D/2D array texture was resized");
let new_width =
std::cmp::max(highest_bit(convert_width as u32) as usize, 16);
let new_height =
std::cmp::max(highest_bit(convert_height as u32) as usize, 16);
conv_data = resize(
&runtime_tp,
upload_data,
conv_data = resize_rgba(
upload_data.into(),
convert_width as u32,
convert_height as u32,
new_width as u32,
new_height as u32,
);
log::warn!(
"3D/2D array texture had to be resized, {}x{} to {}x{}",
convert_width,
convert_height,
new_width,
new_height,
image_color_channels,
new_height
);

convert_width = new_width;
Expand Down Expand Up @@ -314,7 +321,7 @@ impl RenderMapLoading {
.into_par_iter()
.map(|(hash, file)| {
let mut img_data: Vec<u8> = Default::default();
let img = load_png_image(
let img = load_png_image_as_rgba(
&file,
|width, height, color_channel_count| {
img_data.resize(
Expand Down Expand Up @@ -456,10 +463,25 @@ impl RenderMapLoading {
}
}

fn verify_resource(file_ty: &str, file_name: &str, file: &[u8]) -> anyhow::Result<()> {
fn verify_resource(
file_ty: &str,
file_name: &str,
file: &[u8],
allow_hq_assets: bool,
) -> anyhow::Result<()> {
match file_ty {
"png" => {
if let Err(err) = is_png_image_valid(file, Default::default()) {
if let Err(err) = is_png_image_valid(
file,
if allow_hq_assets {
PngValidatorOptions {
max_width: 4096.try_into().unwrap(),
max_height: 4096.try_into().unwrap(),
}
} else {
Default::default()
},
) {
return Err(anyhow!(
"downloaded image resource (png) {}\
is not a valid png file: {}",
Expand Down
4 changes: 2 additions & 2 deletions game/client-ui/src/main_menu/leftbar/main_frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use graphics::handles::{
canvas::canvas::GraphicsCanvasHandle, stream::stream::GraphicsStreamHandle,
};
use graphics_types::{commands::TexFlags, types::GraphicsMemoryAllocationType};
use image::png::load_png_image;
use image::png::load_png_image_as_rgba;
use math::math::vector::vec2;
use ui_base::{style::bg_frame_color, types::UiState};

Expand Down Expand Up @@ -39,7 +39,7 @@ fn update_communities(user_data: &mut UserData) {
let icon = http.download_binary_secure(url).await?.to_vec();

let mut img_mem = None;
let img = load_png_image(&icon, |width, height, _| {
let img = load_png_image_as_rgba(&icon, |width, height, _| {
img_mem = Some(graphics_mt.mem_alloc(
GraphicsMemoryAllocationType::TextureRgbaU8 {
width: width.try_into().unwrap(),
Expand Down
7 changes: 3 additions & 4 deletions game/editor/src/action_logic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ use graphics::{
buffer_object::buffer_object::GraphicsBufferObjectHandle,
texture::texture::GraphicsTextureHandle,
},
image::texture_2d_to_3d,
};
use graphics_types::{commands::TexFlags, types::GraphicsMemoryAllocationType};
use image::png::load_png_image;
use image::{png::load_png_image_as_rgba, utils::texture_2d_to_3d};
use map::{
map::groups::layers::{
design::{
Expand Down Expand Up @@ -628,7 +627,7 @@ pub fn do_action(
act.base.index
);
let mut img_mem = None;
let _ = load_png_image(&act.base.file, |width, height, _| {
let _ = load_png_image_as_rgba(&act.base.file, |width, height, _| {
img_mem = Some(backend_handle.mem_alloc(
GraphicsMemoryAllocationType::TextureRgbaU8 {
width: width.try_into().unwrap(),
Expand Down Expand Up @@ -658,7 +657,7 @@ pub fn do_action(
act.base.index
);
let mut png = Vec::new();
let img = load_png_image(&act.base.file, |width, height, _| {
let img = load_png_image_as_rgba(&act.base.file, |width, height, _| {
png = vec![0; width * height * 4];
&mut png
})?;
Expand Down
7 changes: 3 additions & 4 deletions game/editor/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,10 @@ use graphics::{
stream::stream::GraphicsStreamHandle,
texture::texture::{GraphicsTextureHandle, TextureContainer, TextureContainer2dArray},
},
image::texture_2d_to_3d,
};
use graphics_types::{commands::TexFlags, types::GraphicsMemoryAllocationType};
use hiarc::HiarcTrait;
use image::png::load_png_image;
use image::{png::load_png_image_as_rgba, utils::texture_2d_to_3d};
use map::{
map::{
animations::{AnimBase, AnimPointCurveType, AnimPointPos},
Expand Down Expand Up @@ -504,7 +503,7 @@ impl Editor {
let file = resources.get(&meta.blake3_hash).unwrap();

let mut mem = None;
let _ = load_png_image(file, |width, height, _| {
let _ = load_png_image_as_rgba(file, |width, height, _| {
mem = Some(graphics_mt.mem_alloc(
GraphicsMemoryAllocationType::TextureRgbaU8 {
width: width.try_into().unwrap(),
Expand All @@ -531,7 +530,7 @@ impl Editor {
let file = resources.get(&meta.blake3_hash).unwrap();

let mut png = Vec::new();
let img = load_png_image(
let img = load_png_image_as_rgba(
file,
|width, height, color_chanel_count| {
png.resize(
Expand Down
Loading
Loading